Re: vwait doesn't return after setting TCL_SetVar from a thread
- From: David Gravereaux <davygrvy@xxxxxxxxx>
- Date: Sat, 28 Apr 2007 11:49:34 -0700
zivh@xxxxxxxxx wrote:
On Apr 26, 11:27 am, David Gravereaux <davyg...@xxxxxxxxx> wrote:
My use of that code sample is the following, btw.
signature.asc
1KDownload
proc DataReady {} {
set ::data [tiepie::ADC_GetDataVoltCh 1]
}
# allow for callback when data is ready to be read
tiepie::SetDataReadyCallback DataReady
proc SetGenVoltsAndGetDrainVolts {volts} {
# Set Gen amplitude
tiepie::SetFuncGenAmplitude $volts
after 10
# Kick up a measurement set
::tiepie::ADC_Start
# try doing something productive during the wait
vwait ::data
first, thanks for the detailed answer + the source code.
i have several questions:
1. you need to use the mark so the callback to the asyncEvent function
will be from the context of the original interpreter right?
Yes, exactly. It causes a fine grained yield of the parent thread at the next
command boundary or wakes it up if asleep in the event loop.
2. do i need to set the interpreter in the same modes you had done -
preserve and release to garentee that he is in a stable state?
Tcl_Preserve and Tcl_Release are there to make sure if the script causes the
interp to close, it won't close until the current current Tcl_EvalObj has finished.
The "stable state" part comes by using an event callback. An AsyncProc yield can
be deep in the middle of things causing weird bugs regarding expected scope.
BTW -
didn't saw this function in any official dcumentation (i'm using
8.4.1.4 of activestate binaries).
It's there: <http://www.tcl.tk/man/tcl8.4/TclLib/Preserve.htm> but doesn't mention
use with Tcl_Interp* specifically.
3. i saw that in your tcl script you are waiting on variable data but
i haven't seen any where in your code that you are setting it in any
way - is in under the "script" var? - in my implementation i want to
pass the data to this specific variable and SetVar was my choice.
Just replace my use of Tcl_EvalObj with Tcl_SetVar. You might have to sync with
the AsyncProc coming around to acquire a Tcl_Obj of your data. If Tcl was
compiled for thread support, you can call Tcl_NewXXObj() after Tcl_AsyncMark from
your worker thread context, else you'll have to let the AsyncProc context do that.
This is how I see it with a non-thread support core, which IMHO is the safe
approach when you can't be sure what core capabilities you have. Watch for my
bugs.. You'll need to fill the DataReadyInfo struct when you create the token.
typedef struct {
Tcl_Interp *interp;
Tcl_Obj *var;
Tcl_Obj *value;
} DataReadyInfo;
// thread shared, must sync access.
char * newVarValue;
DWORD WINAPI TestProc(ClientData CD)
{
Tcl_AsyncHandler token = (Tcl_AsyncHandler) CD;
Sleep(20000); //wait 20 sec before writing it
printf("changing the variable - see if effecting the vwait\n");
fflush(stdout);
newVarValue = "changed successfully";
Tcl_AsyncMark(token);
WaitForSingleObject(...);
printf("done setting it - thread is being terminated\n");
fflush(stdout);
return 0;
}
int
VarChangeYield (ClientData clientData, Tcl_Interp *interp, int code)
{
DataReadyEvent *evPtr;
DataReadyInfo *info = (DataReadyInfo *) clientData;
/* Not safe to eval in here, so don't do it! */
evPtr = (DataReadyEvent *) ckalloc(sizeof(DataReadyEvent));
evPtr->header.proc = VarChangeEvent;
// clear old stuff, if used before
if (info->value != NULL) {
Tcl_DecrRefCount(info->value);
}
// pick-up new value;
info->value = Tcl_NewStringObj(newVarValue,-1);
// unpause worker thread
SetEvent(...);
evPtr->info = info;
Tcl_QueueEvent((Tcl_Event *)evPtr, TCL_QUEUE_TAIL);
return code;
}
int
VarChangeEvent (Tcl_Event *evPtr, int flags)
{
Tcl_Interp *interp = ((DataReadyEvent *)evPtr)->info->interp;
Tcl_Obj *var = ((DataReadyEvent *)evPtr)->info->var;
Tcl_Obj *value = ((DataReadyEvent *)evPtr)->info->value;
if (!(flags & TCL_FILE_EVENTS)) {
/* deferred, just file events, please */
return 0;
}
if (!Tcl_InterpDeleted(interp)) {
Tcl_ObjSetVar2(interp, var, NULL, value, 0);
}
return 1;
}
4. do i have to use flag file event? what will happen if i'll put
allevents flag? can i generate a custom flag?
TCL_FILE_EVENT is kind-of all purpose for general I/O. You could change that if
you want. It effects the order of how events are processed.
thanks again for your support
Ziv
--
Susie: You'd get a good grade without doing any work.
Calvin: So?
Susie: It's wrong to get rewards you haven't earned.
Calvin: I've never heard of anyone who couldn't live with that.
Attachment:
signature.asc
Description: OpenPGP digital signature
- References:
- vwait doesn't return after setting TCL_SetVar from a thread
- From: zivh@xxxxxxxxx
- Re: vwait doesn't return after setting TCL_SetVar from a thread
- From: David Gravereaux
- Re: vwait doesn't return after setting TCL_SetVar from a thread
- From: David Gravereaux
- vwait doesn't return after setting TCL_SetVar from a thread
- Prev by Date: Re: What can delay [comm send -async ...]?
- Next by Date: Re: vwait doesn't return after setting TCL_SetVar from a thread
- Previous by thread: Re: vwait doesn't return after setting TCL_SetVar from a thread
- Next by thread: Re: vwait doesn't return after setting TCL_SetVar from a thread
- Index(es):