2 Copyright © 1995-2001, 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 *****************************************************************************/
55 AROS_LIBBASE_EXT_DECL(struct ExecBase
*,SysBase
)
57 /* Prepare semaphore message to be a sent message */
58 bidMsg
->ssm_Message
.mn_Length
=sizeof(struct SemaphoreMessage
);
61 * If ln_Name field of message == 1, then this is a shared message, so
62 * we set the field to NULL. Otherwise, set it to the task requesting
63 * the semaphore. By the end, the ssm_Semaphore field contains the new
64 * owner of the semaphore.
66 if( (IPTR
)(bidMsg
->ssm_Message
.mn_Node
.ln_Name
) == SM_SHARED
)
67 bidMsg
->ssm_Semaphore
= NULL
;
69 bidMsg
->ssm_Semaphore
= (struct SignalSemaphore
*)FindTask(NULL
);
71 /* Arbitrate for the semaphore structure - following like ObtainSema() */
74 sigSem
->ss_QueueCount
++;
78 if( sigSem
->ss_QueueCount
== 0 )
80 /* No, and neither does anybody else - claim it as ours. */
81 sigSem
->ss_Owner
= (struct Task
*)bidMsg
->ssm_Semaphore
;
82 sigSem
->ss_NestCount
++;
83 bidMsg
->ssm_Semaphore
= sigSem
;
84 ReplyMsg((struct Message
*)sigSem
);
87 Otherwise check if we already own it
89 else if( sigSem
->ss_Owner
== (struct Task
*)bidMsg
->ssm_Semaphore
)
92 sigSem
->ss_NestCount
++;
93 bidMsg
->ssm_Semaphore
= sigSem
;
94 ReplyMsg((struct Message
*)sigSem
);
98 It is owned by somebody else, set up the waiter
102 struct SemaphoreRequest
*sr
;
106 * Whoever came up with this obviously has a twisted mind. We
107 * pretend that the SemaphoreMessage is really a SemaphoreRequest.
108 * Now, the code in ReleaseSemaphore that deals with this checks
109 * (after clearing bit 0) whether the sr_Waiter field is NULL. If
110 * so then it is really a SemaphoreMessage and should be returned.
112 * Now the bad part about this is what we are doing. There are two
113 * cases, in the Amiga case (bincompat), we are overwriting the
114 * ln_Type, ln_Pri and (half the) ln_Name fields. In the other
115 * case we are overwriting the ln_Name field completely. Now, in
116 * either case this doesn't matter as they do not contain any
117 * useful information that we haven't already claimed.
119 * Thank goodness C is so type unsafe.
121 sr
= (struct SemaphoreRequest
*)bidMsg
;
122 if (bidMsg
->ssm_Semaphore
!= NULL
)
123 sr
->sr_Waiter
= NULL
;
125 sr
->sr_Waiter
= (APTR
)SM_SHARED
;
127 AddTail((struct List
*)&sigSem
->ss_WaitQueue
, (struct Node
*)bidMsg
);