2 Copyright © 1995-2007, The AROS Development Team. All rights reserved.
5 Desc: Try to lock a semaphore.
8 #include "exec_intern.h"
9 #include "semaphores.h"
10 #include <exec/semaphores.h>
11 #include <proto/exec.h>
13 /*****************************************************************************
17 AROS_LH2(ULONG
, Procure
,
20 AROS_LHA(struct SignalSemaphore
*, sigSem
, A0
),
21 AROS_LHA(struct SemaphoreMessage
*, bidMsg
, A1
),
24 struct ExecBase
*, SysBase
, 90, Exec
)
27 Tries to get a lock on a semaphore in an asynchronous manner.
28 If the semaphore is not free this function will not wait but
29 just post a request to the semaphore. As soon as the semaphore is
30 available the bidMsg will return and make you owner of the semaphore.
33 sigSem - pointer to semaphore structure
34 bidMsg - pointer to a struct SemaphoreMessage. This should lie in
35 public or at least shared memory.
38 Principly none. Don't know. Just ignore it.
41 Locks obtained with Procure() must be released with Vacate().
52 *****************************************************************************/
56 /* Prepare semaphore message to be a sent message */
57 bidMsg
->ssm_Message
.mn_Length
=sizeof(struct SemaphoreMessage
);
60 * If ln_Name field of message == 1, then this is a shared message, so
61 * we set the field to NULL. Otherwise, set it to the task requesting
62 * the semaphore. By the end, the ssm_Semaphore field contains the new
63 * owner of the semaphore.
65 if( (IPTR
)(bidMsg
->ssm_Message
.mn_Node
.ln_Name
) == SM_SHARED
)
66 bidMsg
->ssm_Semaphore
= NULL
;
68 bidMsg
->ssm_Semaphore
= (struct SignalSemaphore
*)FindTask(NULL
);
70 /* Arbitrate for the semaphore structure - following like ObtainSema() */
73 sigSem
->ss_QueueCount
++;
77 if( sigSem
->ss_QueueCount
== 0 )
79 /* No, and neither does anybody else - claim it as ours. */
80 sigSem
->ss_Owner
= (struct Task
*)bidMsg
->ssm_Semaphore
;
81 sigSem
->ss_NestCount
++;
82 bidMsg
->ssm_Semaphore
= sigSem
;
83 ReplyMsg((struct Message
*)sigSem
);
86 Otherwise check if we already own it
88 else if( sigSem
->ss_Owner
== (struct Task
*)bidMsg
->ssm_Semaphore
)
91 sigSem
->ss_NestCount
++;
92 bidMsg
->ssm_Semaphore
= sigSem
;
93 ReplyMsg((struct Message
*)sigSem
);
97 It is owned by somebody else, set up the waiter
101 struct SemaphoreRequest
*sr
;
105 * Whoever came up with this obviously has a twisted mind. We
106 * pretend that the SemaphoreMessage is really a SemaphoreRequest.
107 * Now, the code in ReleaseSemaphore that deals with this checks
108 * (after clearing bit 0) whether the sr_Waiter field is NULL. If
109 * so then it is really a SemaphoreMessage and should be returned.
111 * Now the bad part about this is what we are doing. There are two
112 * cases, in the Amiga case (bincompat), we are overwriting the
113 * ln_Type, ln_Pri and (half the) ln_Name fields. In the other
114 * case we are overwriting the ln_Name field completely. Now, in
115 * either case this doesn't matter as they do not contain any
116 * useful information that we haven't already claimed.
118 * Thank goodness C is so type unsafe.
120 sr
= (struct SemaphoreRequest
*)bidMsg
;
121 if (bidMsg
->ssm_Semaphore
!= NULL
)
122 sr
->sr_Waiter
= NULL
;
124 sr
->sr_Waiter
= (APTR
)SM_SHARED
;
126 AddTail((struct List
*)&sigSem
->ss_WaitQueue
, (struct Node
*)bidMsg
);