Problem with IPC semaphores ...

Davide Libenzi (dlibenzi@maticad.it)
Sun, 12 Sep 1999 13:11:36 +0200 (CEST)


Hi guys,

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/