Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 11 Feb 1999 21:19:30 +0000 (GMT)
From:      Terry Lambert <tlambert@primenet.com>
To:        peter.jeremy@auss2.alcatel.com.au (Peter Jeremy)
Cc:        tlambert@primenet.com, hackers@FreeBSD.ORG
Subject:   Re: portability of shm, mmap, pipes and socket IPC
Message-ID:  <199902112119.OAA10970@usr06.primenet.com>
In-Reply-To: <99Feb11.162122est.40373@border.alcanet.com.au> from "Peter Jeremy" at Feb 11, 99 04:31:46 pm

next in thread | previous in thread | raw e-mail | index | archive | help
> >If the sem_op is a negative integer, and the absolute value of the
> >sem_op is larger than the current value of the semaphore, and the
> >value of (sem_flg&IPC_NOWAIT) is false, then the operation is ignored.
> 
> As far as I can tell, this is handled correctly.
> 
> Looking at v 1.22, this is detected at line 690.  Then follows a debug
> statement "can't do it now" and a break.  The break exits the inner
> for loop (ending at line 717) whick is working thru all the semops
> passed in.  Since we haven't made it through all the semops, we fall
> through lines 725-746, unwinding any partially commited operations.
> Then there's a tsleep() on semaptr (which is the semaphore
> descriptor).  If the tsleep returns normally, the whole thing is
> repeated courtesy of the for loop covering lines 671-786.
> 
> The tsleep is woken up by a semctl() with IPC_RMID, SETVAL, SETALL,
> or a semop() or semexit() that up's any semaphores in that descriptor.

What about a negative initial value setting?

I used this technique on UnixWare to implement an RPC interlock
mechanism that involved setting things up in shared memory in one
process, and processing in another; roughly, the following states:


 99>                       ,----.
                           |    |
                           |    |
                      ,----'    |
            ,----.    |         |
            |    |    |         |
            |    |    |         |
  0>        |    |    |         |
            |    `----'         |
            |                   |
            |                   |
-99>    ----'                   `-----
        listen   call      reset
	     setup    return

I had to implement it a different way on FreeBSD because the
initialization to a negative value failed the addition (the process
slept forever).  When the man page says "absolute value", it *means*
"absolute value".  The zero crossing boundary is broken.  It's needed
to be able to set it up so that if the caller dies/goes away, the
callee has to see an inverted value for the state so it can go back
into listen mode -- in other words, a failure to a reset condition,
even when the return value is unacknowledged.

Since the same parameter area was used by multiple clients of the
"Remote Procedure Call" interface, the rturn *must* be acknowlged,
instead of being implemented as a one-shot.


> EIDRM was added (I believe by sos) sometime after 2.2.6.  It's only
> used by sysv_msg.c and sysv_sem.c - and from what I can see, the code
> is all protected by #ifdef EIDRM's, so the code should work correctly,
> whether or not EIDRM is defined.  Someone with commit priv's just
> needs to remove the comment saying it doesn't exist.

And the #if/#else/EINVAL/#endif.


					Terry Lambert
					terry@lambert.org
---
Any opinions in this posting are my own and not those of my present
or previous employers.

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-hackers" in the body of the message



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199902112119.OAA10970>