From: Mats B. <ma...@pr...> - 2003-11-24 14:23:15
|
Dear all, I've run into a problem with QuickTimeTcl not seen before. I can't say when it started happening, but I run TclTkAqua 8.4.4 and cvs QuickTimeTcl. The problem is that everything gets caught in an Tcl_DoOneEvent(TCL_DONT_WAIT ...). The problem shows up when loading a movie from an url async, where I regularly checks the load state of the movie, and makes a callback to tcl if the load state has changed in any way. I don't see why this happens. The code I use looks something like: resTcl = Tcl_Eval( movPtr->interp, cmd ); Tcl_DoOneEvent( TCL_DONT_WAIT | TCL_ALL_EVENTS ); but I don't remember anymore why the Tcl_DoOneEvent was necessary (if?)... If the Tcl_DoOneEvent is commented out I instead get stuck in the Tcl_Eval call. It's all very weird. Also, if I run the test script below in a vanilla wish, all works ok. But when I run it after started the Coccinella (coccinella.sf.net) then it blocks. I should add that I use Carbon event timers to serve the movies. Two stack traces from PB after pressing the stop button: 0 semaphore_wait_trap 1 pthread_mutex_lock 2 DoActualWait 3 TkMacOSXWaitForEvent 4 Tcl_WaitForEvent 5 Tcl_DoOneEvent( TCL_DONT_WAIT | TCL_ALL_EVENTS ) 0 mach_msg_trap 1 mach_msg 2 CFRunLoopRunInMode 3 CFRunLoopRunSpecific 4 GetEventClass 5 GetKeyboardFocus 6 GetDialogItemAsControl 7 DoActualWait 8 TkMacOSXWaitForEvent 9 Tcl_WaitForEvent 10 Tcl_DoOneEvent( TCL_DONT_WAIT | TCL_ALL_EVENTS ) ---script-------------------- package require QuickTimeTcl proc MyLoadCheck {w msg {err {}}} { puts "w=$w, msg=$msg, err=$err" if {[llength $err]} { puts "Failed" } elseif {(($msg == "playable") || ($msg == "complete")) && ![winfo ismapped $w]} { pack $w update } } set f "http://www.visit.se/~matben/merry.mp3" movie .m -url $f -loadcommand MyLoadCheck Any ideas anyone? Mats |
From: Mats B. <ma...@pr...> - 2003-12-03 15:33:42
|
Update: I was able to find a workaround for this by using Tcl_CreateTimerHandler() with a 0 millisec time. By the way, it's there already in 8.4.2 so it's nothing new. This puts the callback to script level out of the execution path of the Carbon timer which gives a hint to the origin of the problem. I can imagine this; In the Tcl/Tk event loop in the core in an innocent system call the Carbon event timer is fired from low level (mach ?) code and my client code takes over and calls up to the script level, or does an Tcl_DoOneEvent. This makes a reentry in a function of the Tcl event loop in an unexpected way, which screws up things completely. Well, this is only a guess. Lesson: never do anything at the event loop or call script code while being in a Carbon timer. Put the stuff on the Tcl event loop instead for later execution. Question: do we have the same problem with Carbon events? This whole thing makes me feel very uneasy... Best Wishes, Mats Mats Bengtsson wrote: > > Dear all, > > I've run into a problem with QuickTimeTcl not seen before. > I can't say when it started happening, but I run TclTkAqua 8.4.4 > and cvs QuickTimeTcl. The problem is that everything gets caught > in an Tcl_DoOneEvent(TCL_DONT_WAIT ...). The problem shows > up when loading a movie from an url async, where I regularly > checks the load state of the movie, and makes a callback to tcl > if the load state has changed in any way. I don't see why this happens. > The code I use looks something like: > > resTcl = Tcl_Eval( movPtr->interp, cmd ); > Tcl_DoOneEvent( TCL_DONT_WAIT | TCL_ALL_EVENTS ); > > but I don't remember anymore why the Tcl_DoOneEvent was necessary (if?)... > If the Tcl_DoOneEvent is commented out I instead get stuck in the Tcl_Eval call. > It's all very weird. > Also, if I run the test script below in a vanilla wish, all works ok. > But when I run it after started the Coccinella (coccinella.sf.net) then > it blocks. I should add that I use Carbon event timers to serve the movies. > Two stack traces from PB after pressing the stop button: > > 0 semaphore_wait_trap > 1 pthread_mutex_lock > 2 DoActualWait > 3 TkMacOSXWaitForEvent > 4 Tcl_WaitForEvent > 5 Tcl_DoOneEvent( TCL_DONT_WAIT | TCL_ALL_EVENTS ) > > 0 mach_msg_trap > 1 mach_msg > 2 CFRunLoopRunInMode > 3 CFRunLoopRunSpecific > 4 GetEventClass > 5 GetKeyboardFocus > 6 GetDialogItemAsControl > 7 DoActualWait > 8 TkMacOSXWaitForEvent > 9 Tcl_WaitForEvent > 10 Tcl_DoOneEvent( TCL_DONT_WAIT | TCL_ALL_EVENTS ) > > ---script-------------------- > > package require QuickTimeTcl > proc MyLoadCheck {w msg {err {}}} { > puts "w=$w, msg=$msg, err=$err" > if {[llength $err]} { > puts "Failed" > } elseif {(($msg == "playable") || ($msg == "complete")) && ![winfo ismapped > $w]} { > pack $w > update > } > } > set f "http://www.visit.se/~matben/merry.mp3" > movie .m -url $f -loadcommand MyLoadCheck > |
From: Jim I. <ji...@ap...> - 2003-12-03 19:19:00
|
Mats, Sorry I haven't gotten a chance to look into your problem, I have been busy, and my stock of mega-dose Aspirin is too low for this sort of problem right now... But I bet you are right about your guess. In general, I think it is wisest to treat Carbon Timers like signal handlers, do as little as possible in them, get out quickly, and let the main event loop handle your events. Carbon events cause a similar problem. What they do is that one Carbon event can cause other synthetic events to be created. However, these events are not put on the event queue, rather their handlers are called immediately. This means that Tcl will end up handling an event while in the process of handling another, which was causing problems. You have to be especially careful because sometimes the Carbon event mechanism seems to work by having custom handlers change the state of the event, and then pass it on to the rest of the event handling chain (which may be other handlers of this event, or it may be other synthetic events). So deferring handling back to the Tcl event loop may not be possible... Jim On Dec 3, 2003, at 7:29 AM, Mats Bengtsson wrote: > > Update: > > I was able to find a workaround for this by using > Tcl_CreateTimerHandler() > with a 0 millisec time. By the way, it's there already in 8.4.2 so > it's nothing new. > This puts the callback to script level out of the execution path > of the Carbon timer which gives a hint to the origin of the problem. > I can imagine this; In the Tcl/Tk event loop in the core in an > innocent system call the Carbon event timer is fired from low level > (mach ?) code and my client code takes over and calls up to the script > level, > or does an Tcl_DoOneEvent. This makes a reentry in a function of the > Tcl event loop in an unexpected way, which screws up things completely. > Well, this is only a guess. > > Lesson: never do anything at the event loop or call script code while > being in a Carbon timer. Put the stuff on the Tcl event loop instead > for later execution. > > Question: do we have the same problem with Carbon events? > > This whole thing makes me feel very uneasy... > > Best Wishes, Mats > > > Mats Bengtsson wrote: >> >> Dear all, >> >> I've run into a problem with QuickTimeTcl not seen before. >> I can't say when it started happening, but I run TclTkAqua 8.4.4 >> and cvs QuickTimeTcl. The problem is that everything gets caught >> in an Tcl_DoOneEvent(TCL_DONT_WAIT ...). The problem shows >> up when loading a movie from an url async, where I regularly >> checks the load state of the movie, and makes a callback to tcl >> if the load state has changed in any way. I don't see why this >> happens. >> The code I use looks something like: >> >> resTcl = Tcl_Eval( movPtr->interp, cmd ); >> Tcl_DoOneEvent( TCL_DONT_WAIT | >> TCL_ALL_EVENTS ); >> >> but I don't remember anymore why the Tcl_DoOneEvent was necessary >> (if?)... >> If the Tcl_DoOneEvent is commented out I instead get stuck in the >> Tcl_Eval call. >> It's all very weird. >> Also, if I run the test script below in a vanilla wish, all works ok. >> But when I run it after started the Coccinella (coccinella.sf.net) >> then >> it blocks. I should add that I use Carbon event timers to serve the >> movies. >> Two stack traces from PB after pressing the stop button: >> >> 0 semaphore_wait_trap >> 1 pthread_mutex_lock >> 2 DoActualWait >> 3 TkMacOSXWaitForEvent >> 4 Tcl_WaitForEvent >> 5 Tcl_DoOneEvent( TCL_DONT_WAIT | TCL_ALL_EVENTS ) >> >> 0 mach_msg_trap >> 1 mach_msg >> 2 CFRunLoopRunInMode >> 3 CFRunLoopRunSpecific >> 4 GetEventClass >> 5 GetKeyboardFocus >> 6 GetDialogItemAsControl >> 7 DoActualWait >> 8 TkMacOSXWaitForEvent >> 9 Tcl_WaitForEvent >> 10 Tcl_DoOneEvent( TCL_DONT_WAIT | TCL_ALL_EVENTS ) >> >> ---script-------------------- >> >> package require QuickTimeTcl >> proc MyLoadCheck {w msg {err {}}} { >> puts "w=$w, msg=$msg, err=$err" >> if {[llength $err]} { >> puts "Failed" >> } elseif {(($msg == "playable") || ($msg == "complete")) && >> ![winfo ismapped >> $w]} { >> pack $w >> update >> } >> } >> set f "http://www.visit.se/~matben/merry.mp3" >> movie .m -url $f -loadcommand MyLoadCheck >> > > > ------------------------------------------------------- > This SF.net email is sponsored by: SF.net Giveback Program. > Does SourceForge.net help you be more productive? Does it > help you create better code? SHARE THE LOVE, and help us help > YOU! Click Here: http://sourceforge.net/donate/ > _______________________________________________ > Tcl-mac mailing list > Tc...@li... > https://lists.sourceforge.net/lists/listinfo/tcl-mac > -- Jim Ingham ji...@ap... Developer Tools Apple Computer |