I'm having troubles with ipc semaphores in a software I'm developing and
that I plan to license under GPL as soon as it reach a beta version.
It's a mail server that will run on linux, hp-ux and nt that makes large use
of "threads" and ipc semaphores and shared memory.
I've realized a common system independent API for sockets, threads, semaphores
and shared memory.
For now to keep the same hp-ux interface I've implemented:
unsigned long SysCreateThread(int (*pThreadProc)(void *), void *pThreadData)
{
pid_t pid = fork(); /* clone(...) */
if (pid == 0)
exit(pThreadProc(pThreadData));
return (pid);
}
This is the steps the program makes ( in few words ).
The main thread ( A ) create a semaphore with a unique key ( tested ) that is a global variabile:
mlr_key = SysCreateIPCKey();
SYS_SEMAPHORE semid = semget(mlr_key, 1, IPC_CREATE | IPC_EXCL | 0600);
and the semid is OK.
Then it creates N ( four in my case, B1..B4 ) mailer threads ( with the function above )
that connect with the semaphore mlr_key and wait:
static int SysSemLock(SYS_SEMAPHORE SemID, int iCount, int iSemNumber)
{
struct sembuf SemBuf;
ZeroData(SemBuf);
SemBuf.sem_num = iSemNumber;
SemBuf.sem_op = -iCount;
SemBuf.sem_flg = 0;
return (semop((int) SemID, &SemBuf, 1));
}
int MailerThread(void * pThreadData)
{
SYS_SEMAPHORE semid = semget(mlr_key, 1, 0);
...
for (;;)
{
SysSemLock(semid, 1, 0);
printf("thread unlocked\n");
...
/* Process spool */
}
...
}
Then the main thread ( A ) create an SMTP server thread ( C ).
This thread handle SMTP conections and create a new thread for
each connection ( D ).
This thread, after a mail is received push it in the spool directory
and then :
SYS_SEMAPHORE semid = semget(mlr_key, 1, 0);
SysSemLock(semid, -1, 0);
to release a mailer thread ( B1..B4 ).
Now, arrive an SMTP connection, the file is pushed into the spool,
semaphore is successfully get and unlocked but, on linux, mailer thread
never wakeup.
It works fine under hp-ux and nt.
But, when main thread ( A ) stop it do a:
SYS_SEMAPHORE semid = semget(mlr_key, 1, 0);
SysSemLock(semid, -NumMailerThreads, 0);
and this release mailer threads.
0 A Main
/ \
/ \
/ \
/ \
1 Mailers B C SMTP server
\
\
\
\
2 D SMTP session
There are a lot of others semaphores used in my app, and these works fine.
It seems that ipc ops are accepted only along threads that belongs to the
same path ( A-C A-D C-D ) but doesn't work if D try to wakeup B.
And there's no error returned by semop(), it seems like always gone right
but mailer threads continue to sleep.
Any ideas ?
Cheers,
Davide.
-- "Debian, the freedom in freedom."
- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/