flush()
file operation. If you get compilation errors with
kernel versions prior to 2.6.18, change the version test
around the flush assignment. (AT)
Relay()
function. (LM)
clock_getres()
. The header had a macro
defined, but there was no actual function. (AT)
Sendmx()
where success would return the number of
bytes transferred instead of returning zero. (AT)
exec()
and expecting blocked tasks and allocated
names to survive the exec()
call. ***Make the SRR file descriptor close in a child spawned using a call to exec(). This partially addresses a serious problem when using a threaded process to spawn child processes with fork/exec. It's like this:
Linux has the odd behaviour that a multi-threaded program in Linux closes its file descriptors in a sub-thread, even if the file descriptor was originally opened in the main thread. This has the effect of mis-leading the SRR module into believing that the main thread is still running.
Even with this mis-leading information, everything works fine, until you spawn a child process from the sub-thread without ever making an SRR call in that sub-thread. The child process inherits the subthread's SRR file descriptor (which was itself inherited from the main thread), so it can hold this file descriptor open indefinitely. If the child process survives beyond the termination of the main thread, several things can happen: 1) names are held open after a process dies 2) there can be a kernel panic in flush_signals 3) there can be a kernel "Oops" when a timer expires on a process that has already terminated. There may be other effects.
In general, this problem appears not to be solvable. There is no information offered by the kernel to reliably determine that a process has died in truth. We have only the file descriptor to go by.
In most cases, the problem IS solvable. The SRR module now sets the FD_CLOEXEC flag on the SRR file descriptor by default. This is technically a break from the behaviour of QNX, which will allow a process to call exec() without releasing names or unblocking blocked senders. This case is very rare, however. For people who need this behaviour, there is a new function call, SrrSurviveExec() with no arguments, that will give the QNX-like behaviour. It must be called once per thread within a program.
If you need both the QNX-like exec behaviour and the safer child process behaviour, you will have to change one or the other. If you are calling fork+exec in succession to spawn a process, you definitely do not need the QNX-like behaviour.
The slightly more technical explanation is this: Parent mainline (P) starts thread (T), which fork/exec's child (C) which makes no SRR calls. If C survives the death of P, then it will hold open P's file descriptor (FD). In Linux, FD is closed in the parent by T, not by P, so SRR cannot tell that P has died. It uses the final close of FD as evidence that P has died, but C is holding FD open, so P appears to still be active. P does not appear to die until C dies. If P is holding a name, the name will appear to still be active. When C dies, the cleanup code for P could attempt to access a now defunct kernel task structure, which will cause a panic.
If you really want the SRR file descriptor to survive an exec call, make a call to SrrSurviveExec() prior to calling exec(), (but after fork() if you are using it). You would only do this if you wanted to allocate a name to a process that you subsequently spawned, or expected to have processes blocked on the program when the exec call is made, and you want them to continue to block. You must call SrrSurviveExec once in each thread that will call exec(). (AT)
SrrGetpid()
, which returns
the real process ID of the calling thread. Threads in Linux
are assigned unique process IDs, but the getpid()
call in
later kernel versions (post 2.6.3?) returns the process ID of
the thread parent. This makes sense in many cases, but not
for SRRIPC. (AT)
Send()
call. This now
generates ENOMEM consistently. (AT)
alarm()
call
to be compatible with QNX 4. (MC)
SrrUsePthreads(1)
at the start of a
program using pthreads. You still have to ensure that the
registration order (first SRR module call) of the various
threads is consistent with the communication profile among
them. It is wise to call SrrReg()
or some other SRR library
function in the main thread before creating any child threads.
(AT)flush()
event,
since that is where it actually should be. release()
is too
late. (AT)
fork()
by the client. (AT)SrrUsePthreads(1)
;
prior to any other SRRIPC call. To test whether the pthread
support is working, run the program:
srr/exe/pthread
This addition is experimental. Please send us your
feedback. (AT)
recalc_sigpending()
takes an argument based on a regular
expression grep in the sched.h file. (AT)
fork()
. (AST)
Readmsg()
call (mirrors QNX Readmsg()) call, to read data
from the current incoming message. (AS)
Creceive()
,select()
SrrDebug()
to control verbosity of debug messages in a module built
with debugging compiled in.