Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Changes In Branch rfe-notifier-fork Through [a201b97b3e] Excluding Merge-Ins
This is equivalent to a diff from 728fb2f25b to a201b97b3e
|
2013-07-23
| ||
| 09:07 | Add "testfork" test command. Not used in any test-case yet check-in: b425245964 user: jan.nijtmans tags: core-8-5-branch | |
|
2013-07-22
| ||
| 10:57 | Use pthread_atfork() when available. check-in: 94b207274c user: jan.nijtmans tags: rfe-notifier-fork | |
| 10:11 | Test-case should pass on Darwin or with non-threaded build as well. check-in: a201b97b3e user: jan.nijtmans tags: rfe-notifier-fork | |
| 10:10 | Fix bug which hangs iocmd.tf-32.1 check-in: 9ce264b926 user: jan.nijtmans tags: rfe-notifier-fork | |
|
2013-07-21
| ||
| 14:52 | Rebase to core-8-5-branch Add "testfork" test command to be usable in testcase. check-in: 6f69bbba43 user: jan.nijtmans tags: rfe-notifier-fork | |
|
2013-07-08
| ||
| 18:56 | Unbreak MSVC6 debug build (thanks Andreas Kupries!) check-in: d369017148 user: jan.nijtmans tags: trunk | |
| 18:55 | Unbreak MSVC6 debug build (thanks Andreas Kupries!) check-in: 728fb2f25b user: jan.nijtmans tags: core-8-5-branch | |
| 06:49 | Build stub objects with -DSTATIC_BUILD on all platforms. Only important on win32 (already done) and ... check-in: dda8563eba user: jan.nijtmans tags: core-8-5-branch | |
Changes to ChangeLog.
1 2 3 4 5 6 7 | 2013-07-05 Kevin B. Kenny <kennykb@acm.org> * library/tzdata/Africa/Casablanca: * library/tzdata/America/Asuncion: * library/tzdata/Antarctica/Macquarie: * library/tzdata/Asia/Gaza: * library/tzdata/Asia/Hebron: | > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 | 2013-07-17 Harald Oehlmann <oehhar@users.sf.net> * tclUnixNotify.c Tcl_InitNotifier: RFE [a0bc856dcd] Start notifier thread again if we were forked, to solve Rivet bug 55153. 2013-07-05 Kevin B. Kenny <kennykb@acm.org> * library/tzdata/Africa/Casablanca: * library/tzdata/America/Asuncion: * library/tzdata/Antarctica/Macquarie: * library/tzdata/Asia/Gaza: * library/tzdata/Asia/Hebron: |
| ︙ | ︙ |
Added tests/unixForkEvent.test.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
# This file contains a collection of tests for the procedures in the file
# tclUnixNotify.c. Sourcing this file into Tcl runs the tests and
# generates output for errors. No output means no errors were found.
#
# Copyright (c) 1995-1997 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
package require tcltest 2
namespace import -force ::tcltest::*
testConstraint testfork [llength [info commands testfork]]
# Test if the notifier thread is well initialized in a forked interpreter
# by Tcl_InitNotifier
test unixforkevent-1.1 {fork and test writeable event} \
-constraints testfork \
-body {
set folder [makeDirectory unixtestfork]
set pid [testfork]
if {$pid == 0} {
# we are the forked process
set result initialized
set h [open [file join $folder test.txt] w]
fileevent $h writable\
"set result writable;\
after cancel [after 1000 {set result timeout}]"
vwait result
close $h
makeFile $result result.txt $folder
exit
}
# we are the original process
while {![file readable [file join $folder result.txt]]} {}
viewFile result.txt $folder
} \
-result {writable} \
-cleanup {
catch { removeFolder $folder }
}
::tcltest::cleanupTests
return
|
Changes to unix/tclUnixNotfy.c.
| ︙ | ︙ | |||
108 109 110 111 112 113 114 |
Tcl_Condition waitCV; /* Any other thread alerts a notifier that an
* event is ready to be processed by signaling
* this condition variable. */
#endif /* __CYGWIN__ */
int eventReady; /* True if an event is ready to be processed.
* Used as condition flag together with waitCV
* above. */
| | > > > > > > > > > | 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 |
Tcl_Condition waitCV; /* Any other thread alerts a notifier that an
* event is ready to be processed by signaling
* this condition variable. */
#endif /* __CYGWIN__ */
int eventReady; /* True if an event is ready to be processed.
* Used as condition flag together with waitCV
* above. */
#endif /* TCL_THREADS */
} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;
#ifdef TCL_THREADS
/*
* The following static indicates the number of threads that have initialized
* notifiers.
*
* You must hold the notifierMutex lock before accessing this variable.
*/
static int notifierCount = 0;
/*
* The following static stores the process ID of the initialized notifier
* thread. If it changes, we have passed a fork and we should start a new
* notifier thread.
*
* You must hold the notifierMutex lock before accessing this variable.
*/
static pid_t processIDInitialized = 0;
/*
* The following variable points to the head of a doubly-linked list of
* ThreadSpecificData structures for all threads that are currently waiting on
* an event.
*
* You must hold the notifierMutex lock before accessing this list.
*/
|
| ︙ | ︙ | |||
181 182 183 184 185 186 187 | /* * This is the thread ID of the notifier thread that does select. */ static Tcl_ThreadId notifierThread; | | | 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 | /* * This is the thread ID of the notifier thread that does select. */ static Tcl_ThreadId notifierThread; #endif /* TCL_THREADS */ /* * Static routines defined in this file. */ #ifdef TCL_THREADS static void NotifierThreadProc(ClientData clientData); |
| ︙ | ︙ | |||
263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 |
tsdPtr->eventReady = 0;
/*
* Start the Notifier thread if necessary.
*/
Tcl_MutexLock(¬ifierMutex);
if (notifierCount == 0) {
if (TclpThreadCreate(¬ifierThread, NotifierThreadProc, NULL,
TCL_THREAD_STACK_DEFAULT, TCL_THREAD_JOINABLE) != TCL_OK) {
Tcl_Panic("Tcl_InitNotifier: unable to start notifier thread");
}
}
notifierCount++;
/*
* Wait for the notifier pipe to be created.
*/
while (triggerPipe < 0) {
Tcl_ConditionWait(¬ifierCV, ¬ifierMutex, NULL);
}
Tcl_MutexUnlock(¬ifierMutex);
| > > > > > > > > > > > > | | 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 |
tsdPtr->eventReady = 0;
/*
* Start the Notifier thread if necessary.
*/
Tcl_MutexLock(¬ifierMutex);
/*
* Check if my process id changed, e.g. I was forked
* In this case, restart the notifier thread and close the
* pipe to the original notifier thread
*/
if (notifierCount > 0 && processIDInitialized != getpid()) {
notifierCount = 0;
processIDInitialized = 0;
close(triggerPipe);
triggerPipe = -1;
}
if (notifierCount == 0) {
if (TclpThreadCreate(¬ifierThread, NotifierThreadProc, NULL,
TCL_THREAD_STACK_DEFAULT, TCL_THREAD_JOINABLE) != TCL_OK) {
Tcl_Panic("Tcl_InitNotifier: unable to start notifier thread");
}
processIDInitialized = getpid();
}
notifierCount++;
/*
* Wait for the notifier pipe to be created.
*/
while (triggerPipe < 0) {
Tcl_ConditionWait(¬ifierCV, ¬ifierMutex, NULL);
}
Tcl_MutexUnlock(¬ifierMutex);
#endif /* TCL_THREADS */
return (ClientData) tsdPtr;
}
/*
*----------------------------------------------------------------------
*
* Tcl_FinalizeNotifier --
|
| ︙ | ︙ |
Changes to unix/tclUnixTest.c.
| ︙ | ︙ | |||
62 63 64 65 66 67 68 69 70 71 72 73 74 75 | static void TestFileHandlerProc(ClientData clientData, int mask); static int TestfilehandlerCmd(ClientData dummy, Tcl_Interp *interp, int argc, CONST char **argv); static int TestfilewaitCmd(ClientData dummy, Tcl_Interp *interp, int argc, CONST char **argv); static int TestfindexecutableCmd(ClientData dummy, Tcl_Interp *interp, int argc, CONST char **argv); static int TestgetopenfileCmd(ClientData dummy, Tcl_Interp *interp, int argc, CONST char **argv); static int TestgetdefencdirCmd(ClientData dummy, Tcl_Interp *interp, int argc, CONST char **argv); static int TestsetdefencdirCmd(ClientData dummy, Tcl_Interp *interp, int argc, CONST char **argv); int TclplatformtestInit(Tcl_Interp *interp); | > > | 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 | static void TestFileHandlerProc(ClientData clientData, int mask); static int TestfilehandlerCmd(ClientData dummy, Tcl_Interp *interp, int argc, CONST char **argv); static int TestfilewaitCmd(ClientData dummy, Tcl_Interp *interp, int argc, CONST char **argv); static int TestfindexecutableCmd(ClientData dummy, Tcl_Interp *interp, int argc, CONST char **argv); static int TestforkObjCmd(ClientData dummy, Tcl_Interp *interp, int objc, Tcl_Obj *CONST *argv); static int TestgetopenfileCmd(ClientData dummy, Tcl_Interp *interp, int argc, CONST char **argv); static int TestgetdefencdirCmd(ClientData dummy, Tcl_Interp *interp, int argc, CONST char **argv); static int TestsetdefencdirCmd(ClientData dummy, Tcl_Interp *interp, int argc, CONST char **argv); int TclplatformtestInit(Tcl_Interp *interp); |
| ︙ | ︙ | |||
105 106 107 108 109 110 111 112 113 114 115 116 117 118 |
Tcl_CreateCommand(interp, "testchmod", TestchmodCmd,
(ClientData) 0, NULL);
Tcl_CreateCommand(interp, "testfilehandler", TestfilehandlerCmd,
(ClientData) 0, NULL);
Tcl_CreateCommand(interp, "testfilewait", TestfilewaitCmd,
(ClientData) 0, NULL);
Tcl_CreateCommand(interp, "testfindexecutable", TestfindexecutableCmd,
(ClientData) 0, NULL);
Tcl_CreateCommand(interp, "testgetopenfile", TestgetopenfileCmd,
(ClientData) 0, NULL);
Tcl_CreateCommand(interp, "testgetdefenc", TestgetdefencdirCmd,
(ClientData) 0, NULL);
Tcl_CreateCommand(interp, "testsetdefenc", TestsetdefencdirCmd,
(ClientData) 0, NULL);
| > > | 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 |
Tcl_CreateCommand(interp, "testchmod", TestchmodCmd,
(ClientData) 0, NULL);
Tcl_CreateCommand(interp, "testfilehandler", TestfilehandlerCmd,
(ClientData) 0, NULL);
Tcl_CreateCommand(interp, "testfilewait", TestfilewaitCmd,
(ClientData) 0, NULL);
Tcl_CreateCommand(interp, "testfindexecutable", TestfindexecutableCmd,
(ClientData) 0, NULL);
Tcl_CreateObjCommand(interp, "testfork", TestforkObjCmd,
(ClientData) 0, NULL);
Tcl_CreateCommand(interp, "testgetopenfile", TestgetopenfileCmd,
(ClientData) 0, NULL);
Tcl_CreateCommand(interp, "testgetdefenc", TestgetdefencdirCmd,
(ClientData) 0, NULL);
Tcl_CreateCommand(interp, "testsetdefenc", TestsetdefencdirCmd,
(ClientData) 0, NULL);
|
| ︙ | ︙ | |||
529 530 531 532 533 534 535 536 537 538 539 540 541 542 |
" defaultDir\"", NULL);
return TCL_ERROR;
}
Tcl_SetDefaultEncodingDir(argv[1]);
return TCL_OK;
}
/*
*----------------------------------------------------------------------
*
* TestgetdefencdirCmd --
*
* This function implements the "testgetdefenc" command. It is used to
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 |
" defaultDir\"", NULL);
return TCL_ERROR;
}
Tcl_SetDefaultEncodingDir(argv[1]);
return TCL_OK;
}
/*
*----------------------------------------------------------------------
*
* TestforkObjCmd --
*
* This function implements the "testfork" command. It is used to
* fork the Tcl process for specific test cases.
*
* Results:
* A standard Tcl result.
*
* Side effects:
* None.
*
*----------------------------------------------------------------------
*/
static int
TestforkObjCmd(
ClientData clientData, /* Not used. */
Tcl_Interp *interp, /* Current interpreter. */
int objc, /* Number of arguments. */
Tcl_Obj *CONST *objv) /* Argument strings. */
{
pid_t pid;
if (objc != 1) {
Tcl_WrongNumArgs(interp, 1, objv, "");
return TCL_ERROR;
}
pid = fork();
if (pid == -1) {
Tcl_AppendResult(interp,
"Cannot fork", NULL);
return TCL_ERROR;
}
if (pid==0) {
Tcl_InitNotifier();
}
Tcl_SetObjResult(interp, Tcl_NewIntObj(pid));
return TCL_OK;
}
/*
*----------------------------------------------------------------------
*
* TestgetdefencdirCmd --
*
* This function implements the "testgetdefenc" command. It is used to
|
| ︙ | ︙ |