[fpc-pascal] Re: Semaphore problems

Vinzent Hoefler JeLlyFish.software at gmx.net
Mon Jul 24 15:57:33 CEST 2006

On Monday 24 July 2006 10:21, Graeme Geldenhuys wrote:

> procedure TtiPool.CreatePoolSemaphore;
> begin
>   if FSemaphore <> 0 then
>     CloseHandle( FSemaphore ) ;
>   FSemaphore := CreateSemaphore( nil, FiMaxPoolSize, FiMaxPoolSize,
>   sem_destroy( FSemaphore );
>   if sem_init(FSemaphore, 0, 1) <> 0 then
>     raise Exception.Create('Failed to create the semaphore');
> end;

What is FiMaxPoolSize? I assume, it's something like a number of request 
being allowed inside the semaphore-protected region at once?

So in the linux version only one thread is allowed being there.

I suppose you wrote something like

|for i := 0 to 9 do
|   Lock;
|   WriteLn ('Ping');
|end {for};
|for i := 0 to 9 do
|   WriteLn ('Pong');
|   Unlock;
|end {for};

In that case you're experiencing the lock-up when the semaphore is being 
"entered"/locked the second time inside your loop. The counter is zero 
after the first sem_wait and remains that way, because there's nobody 
there to call the sem_post() operation. Well, it may seen as a kind of 
a classical deadlock situation, although there's nothing classical in 
here. ;)

That's what you're experiencing. Although it might appear similar, a 
semaphore is *not* a mutex.

What I don't understand is why you don't use the "SyncObjs" unit where 
almost all the stuff someone ever needs is nicely laid out in a 
portable and object-oriented way.

> >   if sem_wait(FSemaphore) <> 0 then
> >     raise
> > EtiOPFInternalException.Create(cErrorTimedOutWaitingForSemaphore);

BTW, sem_wait() never returns anything else than zero, so checking is 
sort of useless here. There's sem_trywait() for that, if you really 
need to go so low-level.

To the question, what are semaphores. It's quite easily explained: 
Atomic counters, you can only get past if they're non-zero and in that 
case the counter is decremented.


More information about the fpc-pascal mailing list