/Ashok
Not sure this kind of magic is desirable. From the caller's point of
view, it means that in one case the function will block (for a long
time) and in the other it will return immediately, right ? I for one
like to be in control of such things, with a 'blocking' flag or vararg
syntax like [after]...
-Alex
I doubt he's thinking of it as magic, Alexandre; my speculation
is that he has a ten-line script, and wants pleasingly indistin-
guishable results whether he runs inside wish or tclsh.
The answer, I believe, is that there's no good answer. I welcome
correction.
I'm clueless, but you can distinguish between wish and tclsh:
tom@boron:~$ tclsh
% info nameofexecutable
/usr/bin/tclsh
% exit
tom@boron:~$ wish
% info nameofexecutable
/usr/bin/wish
Seems like a crude solution even if it works.
/Ashok
On Sep 3, 8:54 pm, cla...@lairds.us (Cameron Laird) wrote:
> In article <bd52ad41-81a9-4bbf-82a2-d87e8e400...@j19g2000yqk.googlegroups.com>,
Do you want to detect whether an event loop is _already_ running, ie
you are being called from within an event callback, or whether an
event loop is _about_ to be launched, which is technically what
happens when falling back at the end of a wish script, or in an
explicit vwait at the end of an event-driven, pure tclsh script ?
As you might guess, short of a time machine, finding out what the
future has in store is tricky.
Again, you might be more specific as to the nature of that code, the
app domain, etc. The intent is still unclear.
-Alex
If I were reading this and knew nothing of Tcl, I would conclude that
Tcl/Tk sucks badly. Your code has to change based upon an unrelated
extension (Tk)? Problem is I know next to nothing about Tk and only a
little bit more about the event loop.
Anyway, the only facts are that your application works fine without
Tk, but must be aware of operating in a Tk environment. My guess is
that if you do [vwait forever] there is no possibility for Tk to get
loaded, but who knows. What happens if Tk loads after your [vwait
forever]?
you can call vwait in all cases.
just do it with a [catch].
little testscript:
#!/usr/bin/tclsh
# if no eventloop is running this will error out
catch {vwait forever} cerr
# with: "can't wait for variable "forever": would wait forever"
puts cerr1:$cerr
package require Tk
button .b -command {set forever happy} -text weiter
pack .b
catch {vwait forever} cerr
puts cerr2:$cerr:$forever
exit
uwe
So long as you accept the risk of Tk's problems with that.
See Feature Request 456548.
> just do it with a [catch].
Um, why? What error are you expecting that a [catch] would
be the right remedy.
--
| Don Porter Mathematical and Computational Sciences Division |
| donald...@nist.gov Information Technology Laboratory |
| http://math.nist.gov/~DPorter/ NIST |
|______________________________________________________________________|
After reading about vwait: apparently it nests: [vwait x] ... [vwait
y] waits for y then x.
This is no different than any other code. [for ....] [for ...]
requires the second 'for' to finish before the first can finish. Maybe
the real problem is using a dummy variable like "forever" which never
gets set in a reusable code fragment/library...that is [vwait forever]
is not reusable. This interpretation seems reasonable and is free of
bugs.
He did that to catch "would wait forever", in order to detect the fact
that no event sources are present. Which is a reasonable approximation
of "no event loop at the end", though not perfect. (eg if this code is
called at startup and handlers are rigged later, it will make the
wrong decision).
But anyway the OP's motivation for doing this escapes me.
-Alex
My primary motivation, as Cameron guessed, is to have a script that
can be passed to either wish or tclsh. The script itself needs an
event loop to be running, for example it might be a simple network
server using async sockets.
Doing a 'wish foo.tcl' and 'tclsh foo.tcl' should both result in the
network server running and responding to requests. Doing a source
foo.tcl inside wish (or tkcon) and tclsh should also result in the
same.
What I currently do is check in the script if Tk is loaded and if not,
do a 'vwait forever' to kick off the event loop (of course after
setting up the async i/o). I was not entirely happy with this because
I do not want to do the vwait if in fact it is being sourced by some
modified tclsh (without Tk) that is running its own event loop.
Here is a concrete example: I have a single file http server,
myhttpserver.tcl.
- if I do a 'tclsh myhttpserver.tcl' I want to run as a standalone web
server and need to do a vwait to get the event loop running
- if I do a 'wish myhttpserver.tcl' I want the same thing except I
should NOT do a vwait if the event loop is already running.
- if a tclsh application which is already running an event loop does a
'source myhttpserver.tcl', I want to run as an embedded http server
and I very clearly should not be doing a vwait.
What checks should I have in myhttpserver.tcl to meet all three
objectives above?
The simplest solution is of course to have the caller specify/control
whether a vwait is required or not. I was hoping to be able to
automatically detect this, that's all.
Hope that clarifies my original question.
/Ashok
On Sep 4, 11:41 am, Alexandre Ferrieux <alexandre.ferri...@gmail.com>
wrote:
This one is OK :)
> - if I do a 'wish myhttpserver.tcl' I want the same thing except I
> should NOT do a vwait if the event loop is already running.
Why would one do that ? What's the purpose of starting a GUI-less app
with wish ?
Do you try to open pdf files with Audacity ???
> - if a tclsh application which is already running an event loop does a
> 'source myhttpserver.tcl', I want to run as an embedded http server
> and I very clearly should not be doing a vwait.
Yes and this is a programmatically different case: 'source
myhttpserver.tcl' is explicitly written. So, without much effort, the
programmer could for example set a global variable before sourcing, or
source a different file.
If I were in your shoes, I would simply distribute two files:
- a.tcl containing the bulk of the code, no vwait
- b.tcl containing "source a.tcl;vwait forever"
and then let the programmer use his brains and fingers.
Bottom line: when situations are clearly different in the caller's
site, it is not a good idea to make the API lose the info and
rediscover it afterwards.
-Alex
> What checks should I have in myhttpserver.tcl to meet all three
> objectives above?
At the end your "started with eventloop" script will linger
at the file end ( doing an implicit "vwait forever" ).
As far as I can see you can have a catch {vwait forever}
in that position ( and in all cases ) without detrimental
effects?
uwe
To check if your script is the main application, you can use the {$argv0
eq [info script]} check. There is no reliable way to determine if the
event loop is running, short of creating an event and seeing if it
occurs or your script exits :-)
-- Neil
This is excellent advice, I recommend a front-end script, one for each
situation:
myhttpserver-for-wish.tcl
myhttpserver-for-tclsh.tcl
In fact, I like to abstract the entire "http server" functionality
away from the socket code, so I can use stdin/stdout/pipes as well as
socket or add tcl threads:
http://www.junom.com/gitweb/gitweb.perl?p=tnt.git;a=tree;f=packages/nsd/tcl
That's what I currently do and I guess I'll stick with it.
/Ashok
>
> If I were in your shoes, I would simply distribute two files:
>
> - a.tcl containing the bulk of the code, no vwait
> - b.tcl containing "source a.tcl;vwait forever"
>
> and then let the programmer use his brains and fingers.
>
> Bottom line: when situations are clearly different in the caller's
> site, it is not a good idea to make the API lose the info and
> rediscover it afterwards.
Well, yes and no. There is some validity to what you say. But there is
also some desirability to have the software figure out the environment
and Do The Right Thing without bothering the programmer, *if
possible*.
/Ashok
On unix [vwait] errors out when no further events _can_
possibly be generated.
i.e. no eventloop for X, no pending [after] and no [filevent]
for open files waiting for IO ( or anything similar ).
The (uncaught) generated error will reflect into program exit status.
uwe
The difference is that Tcl on Windows is built threaded normally (at a
low level, there are always threads involved anyway due to the way
that Windows works) and Tcl on Unix is built unthreaded by default.
Threaded builds of Tcl do not detect when there are no event sources;
it's unfortunately just too difficult (e.g., there may be non-Tcl
threads that can produce events).
Donal.