diff options
Diffstat (limited to 'generic/tclIORChan.c')
-rw-r--r-- | generic/tclIORChan.c | 197 |
1 files changed, 103 insertions, 94 deletions
diff --git a/generic/tclIORChan.c b/generic/tclIORChan.c index b64a32e..ac19b45 100644 --- a/generic/tclIORChan.c +++ b/generic/tclIORChan.c @@ -15,7 +15,7 @@ * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tclIORChan.c,v 1.32 2008/04/25 21:27:09 das Exp $ + * RCS: @(#) $Id: tclIORChan.c,v 1.33 2008/04/27 22:21:30 dkf Exp $ */ #include <tclInt.h> @@ -63,16 +63,16 @@ static Tcl_ChannelType tclRChannelType = { ReflectClose, /* Close channel, clean instance data */ ReflectInput, /* Handle read request */ ReflectOutput, /* Handle write request */ - ReflectSeek, /* Move location of access point. NULL'able */ - ReflectSetOption, /* Set options. NULL'able */ - ReflectGetOption, /* Get options. NULL'able */ + ReflectSeek, /* Move location of access point. NULL'able */ + ReflectSetOption, /* Set options. NULL'able */ + ReflectGetOption, /* Get options. NULL'able */ ReflectWatch, /* Initialize notifier */ - NULL, /* Get OS handle from the channel. NULL'able */ - NULL, /* No close2 support. NULL'able */ - ReflectBlock, /* Set blocking/nonblocking. NULL'able */ - NULL, /* Flush channel. Not used by core. NULL'able */ - NULL, /* Handle events. NULL'able */ - ReflectSeekWide, /* Move access point (64 bit). NULL'able */ + NULL, /* Get OS handle from the channel. NULL'able */ + NULL, /* No close2 support. NULL'able */ + ReflectBlock, /* Set blocking/nonblocking. NULL'able */ + NULL, /* Flush channel. Not used by core. NULL'able */ + NULL, /* Handle events. NULL'able */ + ReflectSeekWide, /* Move access point (64 bit). NULL'able */ NULL, /* thread action */ NULL, /* truncate */ }; @@ -342,7 +342,8 @@ typedef struct ForwardingEvent { struct ForwardingResult { Tcl_ThreadId src; /* Originating thread. */ Tcl_ThreadId dst; /* Thread the op was forwarded to. */ - Tcl_Interp* dsti; /* Interpreter in the thread the op was forwarded to. */ + Tcl_Interp *dsti; /* Interpreter in the thread the op was + * forwarded to. */ /* * Note regarding 'dsti' above: Its information is also available via the * chain evPtr->rcPtr->interp, however, as can be seen, two more @@ -364,7 +365,7 @@ typedef struct ThreadSpecificData { * per-thread version of the per-interpreter map. */ - ReflectedChannelMap* rcmPtr; + ReflectedChannelMap *rcmPtr; } ThreadSpecificData; static Tcl_ThreadDataKey dataKey; @@ -389,7 +390,7 @@ TCL_DECLARE_MUTEX(rcForwardMutex) */ static void ForwardOpToOwnerThread(ReflectedChannel *rcPtr, - ForwardedOperation op, const VOID *param); + ForwardedOperation op, const void *param); static int ForwardProc(Tcl_Event *evPtr, int mask); static void SrcExitProc(ClientData clientData); @@ -512,9 +513,11 @@ TclChanCreateObjCmd( int methods; /* Bitmask for supported methods. */ Channel *chanPtr; /* 'chan' resolved to internal struct. */ Tcl_Obj *err; /* Error message */ - ReflectedChannelMap* rcmPtr; /* Map of reflected channels with handlers in this interp */ - Tcl_HashEntry* hPtr; /* Entry in the above map */ - int isNew; /* Placeholder. */ + ReflectedChannelMap *rcmPtr; + /* Map of reflected channels with handlers in + * this interp. */ + Tcl_HashEntry *hPtr; /* Entry in the above map */ + int isNew; /* Placeholder. */ /* * Syntax: chan create MODE CMDPREFIX @@ -714,18 +717,16 @@ TclChanCreateObjCmd( Tcl_RegisterChannel(interp, chan); rcmPtr = GetReflectedChannelMap (interp); - hPtr = Tcl_CreateHashEntry(&rcmPtr->map, - chanPtr->state->channelName, &isNew); - if (!isNew) { - if (chanPtr != Tcl_GetHashValue(hPtr)) { - Tcl_Panic("TclChanCreateObjCmd: duplicate channel names"); - } + hPtr = Tcl_CreateHashEntry(&rcmPtr->map, chanPtr->state->channelName, + &isNew); + if (!isNew && chanPtr != Tcl_GetHashValue(hPtr)) { + Tcl_Panic("TclChanCreateObjCmd: duplicate channel names"); } Tcl_SetHashValue(hPtr, chan); #ifdef TCL_THREADS rcmPtr = GetThreadReflectedChannelMap(); - hPtr = Tcl_CreateHashEntry(&rcmPtr->map, - chanPtr->state->channelName, &isNew); + hPtr = Tcl_CreateHashEntry(&rcmPtr->map, chanPtr->state->channelName, + &isNew); Tcl_SetHashValue(hPtr, chan); #endif @@ -736,7 +737,7 @@ TclChanCreateObjCmd( Tcl_SetObjResult(interp, rcId); return TCL_OK; - error: + error: /* * Signal to ReflectClose to not call 'finalize'. */ @@ -793,8 +794,9 @@ TclChanPostEventObjCmd( /* Its associated driver structure */ ReflectedChannel *rcPtr; /* Associated instance data */ int events; /* Mask of events to post */ - ReflectedChannelMap* rcmPtr; /* Map of reflected channels with handlers in this interp */ - Tcl_HashEntry* hPtr; /* Entry in the above map */ + ReflectedChannelMap *rcmPtr;/* Map of reflected channels with handlers in + * this interp. */ + Tcl_HashEntry *hPtr; /* Entry in the above map */ /* * Number of arguments... @@ -900,7 +902,7 @@ TclChanPostEventObjCmd( * Channel error message marshalling utilities. */ -static Tcl_Obj* +static Tcl_Obj * MarshallError( Tcl_Interp *interp) { @@ -1043,8 +1045,9 @@ ReflectClose( ReflectedChannel *rcPtr = (ReflectedChannel *) clientData; int result; /* Result code for 'close' */ Tcl_Obj *resObj; /* Result data for 'close' */ - ReflectedChannelMap* rcmPtr; /* Map of reflected channels with handlers in this interp */ - Tcl_HashEntry* hPtr; /* Entry in the above map */ + ReflectedChannelMap *rcmPtr;/* Map of reflected channels with handlers in + * this interp */ + Tcl_HashEntry *hPtr; /* Entry in the above map */ if (interp == NULL) { /* @@ -1136,18 +1139,18 @@ ReflectClose( * thread and then was moved here. */ - rcmPtr = GetReflectedChannelMap (interp); - hPtr = Tcl_FindHashEntry (&rcmPtr->map, - Tcl_GetChannelName (rcPtr->chan)); + rcmPtr = GetReflectedChannelMap(interp); + hPtr = Tcl_FindHashEntry(&rcmPtr->map, + Tcl_GetChannelName(rcPtr->chan)); if (hPtr) { - Tcl_DeleteHashEntry (hPtr); + Tcl_DeleteHashEntry(hPtr); } #ifdef TCL_THREADS rcmPtr = GetThreadReflectedChannelMap(); - hPtr = Tcl_FindHashEntry (&rcmPtr->map, - Tcl_GetChannelName (rcPtr->chan)); + hPtr = Tcl_FindHashEntry(&rcmPtr->map, + Tcl_GetChannelName(rcPtr->chan)); if (hPtr) { - Tcl_DeleteHashEntry (hPtr); + Tcl_DeleteHashEntry(hPtr); } #endif @@ -1690,7 +1693,7 @@ ReflectGetOption( * The bypass functions are not required. */ - ReflectedChannel *rcPtr = (ReflectedChannel*) clientData; + ReflectedChannel *rcPtr = clientData; Tcl_Obj *optionObj; Tcl_Obj *resObj; /* Result data for 'configure' */ int listc; @@ -2064,7 +2067,7 @@ FreeReflectedChannel( * Delete a cloned ChannelType structure. */ - ckfree((char*) chanPtr->typePtr); + ckfree((char *) chanPtr->typePtr); } n = rcPtr->argc - 2; @@ -2078,8 +2081,8 @@ FreeReflectedChannel( Tcl_DecrRefCount(rcPtr->argv[n+1]); - ckfree((char*) rcPtr->argv); - ckfree((char*) rcPtr); + ckfree((char *) rcPtr->argv); + ckfree((char *) rcPtr); } /* @@ -2267,7 +2270,7 @@ static ReflectedChannelMap * GetReflectedChannelMap( Tcl_Interp *interp) { - ReflectedChannelMap* rcmPtr = Tcl_GetAssocData(interp, RCMKEY, NULL); + ReflectedChannelMap *rcmPtr = Tcl_GetAssocData(interp, RCMKEY, NULL); if (rcmPtr == NULL) { rcmPtr = (ReflectedChannelMap *) ckalloc(sizeof(ReflectedChannelMap)); @@ -2303,10 +2306,10 @@ DeleteReflectedChannelMap( ClientData clientData, /* The per-interpreter data structure. */ Tcl_Interp *interp) /* The interpreter being deleted. */ { - ReflectedChannelMap* rcmPtr; /* The map */ + ReflectedChannelMap *rcmPtr; /* The map */ Tcl_HashSearch hSearch; /* Search variable. */ Tcl_HashEntry *hPtr; /* Search variable. */ - ReflectedChannel* rcPtr; + ReflectedChannel *rcPtr; Tcl_Channel chan; #ifdef TCL_THREADS @@ -2318,7 +2321,7 @@ DeleteReflectedChannelMap( /* * Delete all entries. The channels may have been closed already, or will * be closed later, by the standard IO finalization of an interpreter - * under destruction. Except for the channels which were moved to a + * under destruction. Except for the channels which were moved to a * different interpreter and/or thread. They do not exist from the IO * systems point of view and will not get closed. Therefore mark all as * dead so that any future access will cause a proper error. For channels @@ -2329,14 +2332,12 @@ DeleteReflectedChannelMap( rcmPtr = clientData; for (hPtr = Tcl_FirstHashEntry(&rcmPtr->map, &hSearch); - hPtr != NULL; - hPtr = Tcl_FirstHashEntry(&rcmPtr->map, &hSearch)) { - - chan = (Tcl_Channel) Tcl_GetHashValue (hPtr); + hPtr != NULL; + hPtr = Tcl_FirstHashEntry(&rcmPtr->map, &hSearch)) { + chan = (Tcl_Channel) Tcl_GetHashValue (hPtr); rcPtr = (ReflectedChannel *) Tcl_GetChannelInstanceData(chan); rcPtr->interp = NULL; - Tcl_DeleteHashEntry(hPtr); } Tcl_DeleteHashTable(&rcmPtr->map); @@ -2356,10 +2357,13 @@ DeleteReflectedChannelMap( Tcl_MutexLock(&rcForwardMutex); for (resultPtr = forwardList; - resultPtr != NULL; - resultPtr = resultPtr->nextPtr) { + resultPtr != NULL; + resultPtr = resultPtr->nextPtr) { if (resultPtr->dsti != interp) { - /* Ignore results/events for other interpreters. */ + /* + * Ignore results/events for other interpreters. + */ + continue; } @@ -2389,14 +2393,16 @@ DeleteReflectedChannelMap( rcmPtr = GetThreadReflectedChannelMap(); for (hPtr = Tcl_FirstHashEntry(&rcmPtr->map, &hSearch); - hPtr != NULL; - hPtr = Tcl_NextHashEntry(&hSearch)) { - - chan = (Tcl_Channel) Tcl_GetHashValue (hPtr); + hPtr != NULL; + hPtr = Tcl_NextHashEntry(&hSearch)) { + chan = (Tcl_Channel) Tcl_GetHashValue (hPtr); rcPtr = (ReflectedChannel *) Tcl_GetChannelInstanceData(chan); if (rcPtr->interp != interp) { - /* Ignore entries for other interpreters */ + /* + * Ignore entries for other interpreters. + */ + continue; } @@ -2426,12 +2432,13 @@ DeleteReflectedChannelMap( */ static ReflectedChannelMap * -GetThreadReflectedChannelMap() +GetThreadReflectedChannelMap(void) { ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); if (!tsdPtr->rcmPtr) { - tsdPtr->rcmPtr = (ReflectedChannelMap *) ckalloc(sizeof(ReflectedChannelMap)); + tsdPtr->rcmPtr = (ReflectedChannelMap *) + ckalloc(sizeof(ReflectedChannelMap)); Tcl_InitHashTable(&tsdPtr->rcmPtr->map, TCL_STRING_KEYS); Tcl_CreateThreadExitHandler(DeleteThreadReflectedChannelMap, NULL); } @@ -2464,13 +2471,8 @@ DeleteThreadReflectedChannelMap( Tcl_HashSearch hSearch; /* Search variable. */ Tcl_HashEntry *hPtr; /* Search variable. */ Tcl_ThreadId self = Tcl_GetCurrentThread(); - - ReflectedChannelMap* rcmPtr; /* The map */ - Tcl_Channel chan; - ReflectedChannel* rcPtr; + ReflectedChannelMap *rcmPtr; /* The map */ ForwardingResult *resultPtr; - ForwardingEvent *evPtr; - ForwardParam *paramPtr; /* * The origin thread for one or more reflected channels is gone. @@ -2487,10 +2489,16 @@ DeleteThreadReflectedChannelMap( Tcl_MutexLock(&rcForwardMutex); for (resultPtr = forwardList; - resultPtr != NULL; - resultPtr = resultPtr->nextPtr) { + resultPtr != NULL; + resultPtr = resultPtr->nextPtr) { + ForwardingEvent *evPtr; + ForwardParam *paramPtr; + if (resultPtr->dst != self) { - /* Ignore results/events for other threads. */ + /* + * Ignore results/events for other threads. + */ + continue; } @@ -2519,14 +2527,13 @@ DeleteThreadReflectedChannelMap( rcmPtr = GetThreadReflectedChannelMap(); for (hPtr = Tcl_FirstHashEntry(&rcmPtr->map, &hSearch); - hPtr != NULL; - hPtr = Tcl_FirstHashEntry(&rcmPtr->map, &hSearch)) { - - chan = (Tcl_Channel) Tcl_GetHashValue (hPtr); - rcPtr = (ReflectedChannel *) Tcl_GetChannelInstanceData(chan); + hPtr != NULL; + hPtr = Tcl_FirstHashEntry(&rcmPtr->map, &hSearch)) { + Tcl_Channel chan = (Tcl_Channel) Tcl_GetHashValue(hPtr); + ReflectedChannel *rcPtr = (ReflectedChannel *) + Tcl_GetChannelInstanceData(chan); rcPtr->interp = NULL; - Tcl_DeleteHashEntry(hPtr); } @@ -2537,7 +2544,7 @@ static void ForwardOpToOwnerThread( ReflectedChannel *rcPtr, /* Channel instance */ ForwardedOperation op, /* Forwarded driver operation */ - const VOID *param) /* Arguments */ + const void *param) /* Arguments */ { Tcl_ThreadId dst = rcPtr->thread; ForwardingEvent *evPtr; @@ -2557,7 +2564,7 @@ ForwardOpToOwnerThread( * appropriate error. Do not forget to unlock the mutex on this path. */ - ForwardSetStaticError((ForwardParam *)param, msg_send_dstlost); + ForwardSetStaticError((ForwardParam *) param, msg_send_dstlost); Tcl_MutexUnlock(&rcForwardMutex); return; } @@ -2575,8 +2582,8 @@ ForwardOpToOwnerThread( evPtr->rcPtr = rcPtr; evPtr->param = (ForwardParam *) param; - resultPtr->src = Tcl_GetCurrentThread(); - resultPtr->dst = dst; + resultPtr->src = Tcl_GetCurrentThread(); + resultPtr->dst = dst; resultPtr->dsti = rcPtr->interp; resultPtr->done = NULL; resultPtr->result = -1; @@ -2591,9 +2598,9 @@ ForwardOpToOwnerThread( /* * Ensure cleanup of the event if the origin thread exits while this event - * is pending or in progress. Exitus of the destination thread is handled - * by DeleteThreadReflectionChannelMap(), this is set up by - * GetThreadReflectedChannelMap(). This is what we use the 'forwardList' + * is pending or in progress. Exit of the destination thread is handled by + * DeleteThreadReflectionChannelMap(), this is set up by + * GetThreadReflectedChannelMap(). This is what we use the 'forwardList' * (see above) for. */ @@ -2625,8 +2632,8 @@ ForwardOpToOwnerThread( } /* - * Unlink result from the forwarder list. - * No need to lock. Either still locked, or locked by the ConditionWait + * Unlink result from the forwarder list. No need to lock. Either still + * locked, or locked by the ConditionWait */ TclSpliceOut(resultPtr, forwardList); @@ -2647,7 +2654,7 @@ ForwardOpToOwnerThread( Tcl_DeleteThreadExitHandler(SrcExitProc, (ClientData) evPtr); result = resultPtr->result; - ckfree((char*) resultPtr); + ckfree((char *) resultPtr); } static int @@ -2674,8 +2681,10 @@ ForwardProc( Tcl_Interp *interp = rcPtr->interp; ForwardParam *paramPtr = evPtr->param; Tcl_Obj *resObj = NULL; /* Interp result of InvokeTclMethod */ - ReflectedChannelMap* rcmPtr; /* Map of reflected channels with handlers in this interp */ - Tcl_HashEntry* hPtr; /* Entry in the above map */ + ReflectedChannelMap *rcmPtr; + /* Map of reflected channels with handlers in + * this interp. */ + Tcl_HashEntry *hPtr; /* Entry in the above map */ /* * Ignore the event if no one is waiting for its result anymore. @@ -2715,15 +2724,15 @@ ForwardProc( * 'postevent') from finding and dereferencing a dangling pointer. */ - rcmPtr = GetReflectedChannelMap (interp); - hPtr = Tcl_FindHashEntry (&rcmPtr->map, - Tcl_GetChannelName (rcPtr->chan)); - Tcl_DeleteHashEntry (hPtr); + rcmPtr = GetReflectedChannelMap(interp); + hPtr = Tcl_FindHashEntry(&rcmPtr->map, + Tcl_GetChannelName(rcPtr->chan)); + Tcl_DeleteHashEntry(hPtr); rcmPtr = GetThreadReflectedChannelMap(); - hPtr = Tcl_FindHashEntry (&rcmPtr->map, - Tcl_GetChannelName (rcPtr->chan)); - Tcl_DeleteHashEntry (hPtr); + hPtr = Tcl_FindHashEntry(&rcmPtr->map, + Tcl_GetChannelName(rcPtr->chan)); + Tcl_DeleteHashEntry(hPtr); FreeReflectedChannel(rcPtr); break; |