https://issues.apache.org/bugzilla/show_bug.cgi?id=55153

--- Comment #3 from Harald Oehlmann <harald.oehlm...@elmicron.de> ---
Am Donnerstag, 4. Juli 2013 14:30:27 UTC+2 schrieb Harald Oehlmann:
> Am Mittwoch, 3. Juli 2013 13:06:31 UTC+2 schrieb Alexandre Ferrieux:
> 
> > I'd bet the next thing to do is to recompile Tcl with debug symbols, break 
> > in gdb in Tcl_CreateFileHandler, and single-step there to see what doesn't 
> > pass through. 

I suppose I have found something.
When Apache starts, there are (at least) 2 processes, one owned by root and one
owned by user apache:

ps -L aux
USER       PID   LWP %CPU NLWP %MEM    VSZ   RSS TTY      STAT START   TIME
COMMAND
root      1997  1997  0.0    2  1.4 393536 14704 ?        Tsl  15:21   0:00
/usr/sbin/httpd
root      1997  2000  0.0    2  1.4 393536 14704 ?        Tsl  15:21   0:00
/usr/sbin/httpd
apache    1999  1999  0.0    1  0.7 391472  7292 ?        S    15:21   0:00
/usr/sbin/httpd
apache    2001  2001  0.0    1  0.9 394648  9724 ?        S    15:21   0:00
/usr/sbin/httpd

The process 1997 is the controler process, the others are final handler
processes.

I run two gdb, one attached to 1997, one attached to 2001.

The first has 2 threads:

(gdb) info thread
* 2 Thread 0x7fb15f77b700 (LWP 2000)  NotifierThreadProc (clientData=0x0) at
/home/admin/test/tcl8.6.0/unix/tclUnixNotfy.c:1186
  1 Thread 0x7fb16db9c7e0 (LWP 1997)  0x00007fb16c1d24f3 in select () at
../sysdeps/unix/syscall-template.S:82

The Thread 2 (LWP 2000) runs the TCL notifier function "NotifierThreadProc".

The second (ID 2001) has only one thread and runs the tcl interpreter:
(gdb) info threads
* 1 Thread 0x7fb16db9c7e0 (LWP 2001)  0x00007fb16c1d9f03 in epoll_wait () at
../sysdeps/unix/syscall-template.S:82

In thread 1 of process 2001, the procedure Tcl_CreateFileHandler is called, the
file handle to monitor is written in a thread specific data memory area and ""
is written to the communication pipe.

In thread 2 of process 1997 (LWP2000), in NotifierThreadProc the write to the
pipe is recognized by the select and the shared memory is checked. As it is
another process, the data does not pass.

So, the pipe connection works, but there is no shared memory and thus passing
the file descriptor to select on does not work. In addition, the file
description of process 2001 would propably not by valid in process 1997, LWP
2000.

More in detail, there is a shared variable "waitingListPtr".
This is set to a value in one process and remains zero on the other side.

Here are some details:

*** tsdPtr in procedure Tcl_CreateFileHandler, Process 2001:

 523         ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
(gdb) print tsdPtr
$1 = (ThreadSpecificData *) 0x7fb16eb9f6a0

*** and the memory configuration just before writing to the pipe:
Procedure Tcl_WaitForEvent in Process 2001:

 907             tsdPtr->prevPtr = 0;
 908             waitingListPtr = tsdPtr;
(gdb) print &waitingListPtr
$5 = (ThreadSpecificData **) 0x7fb16260ee88
(gdb) print waitingListPtr
$3 = (ThreadSpecificData *) 0x7fb16eb9f6a0
(gdb) print *waitingListPtr
$4 = {firstFileHandlerPtr = 0x7fb16ec8d7b0, checkMasks = {readable =
{__fds_bits = {0 <repeats 16 times>}}, writable = {__fds_bits = {1048576, 0
<repeats 15 times>}}, exception = {__fds_bits = {0 <repeats 16 times>}}},
readyMasks = {readable = {__fds_bits = {0 <repeats 16 times>}}, writable =
{__fds_bits = {0 <repeats 16 times>}}, exception = {__fds_bits = {0 <repeats 16
times>}}}, numFdBits = 21, onList = 1, pollState = 0, nextPtr = 0x0, prevPtr =
0x0, waitCV = 0x7fb16ec83850, eventReady = 0}
 909             tsdPtr->onList = 1;
(gdb) print tsdPtr
$2 = (ThreadSpecificData *) 0x7fb16eb9f6a0
 910 
 911             if ((write(triggerPipe, "", 1) == -1) && (errno != EAGAIN)) {

*** and now the notifier thread in Process 1997, thread 2 (LWP 2000):
procedure NotifierThreadProc

1186         Tcl_MutexLock(&notifierMutex);
1187         for (tsdPtr = waitingListPtr; tsdPtr; tsdPtr = tsdPtr->nextPtr) {
(gdb) print &waitingListPtr
$3 = (ThreadSpecificData **) 0x7fb16260ee88
(gdb) print waitingListPtr
$2 = (ThreadSpecificData *) 0x0

---

The address of waitingListPtr is identical in the two threads but not the data.
I suppose, this is due to the fork of the parent thread...

---

Well, I suppose, this thread configuration is not as intended.
Each tcl worker process should have its notifier thread...

Thanks anybody to look into this.

Thank you,
Harald

-- 
You are receiving this mail because:
You are the assignee for the bug.

---------------------------------------------------------------------
To unsubscribe, e-mail: rivet-dev-unsubscr...@tcl.apache.org
For additional commands, e-mail: rivet-dev-h...@tcl.apache.org

Reply via email to