6 #include <exec/types.h>
7 #include <utility/hooks.h>
9 #include <dos/dostags.h>
13 #include <proto/dos.h>
14 #include <proto/exec.h>
16 #include <proto/scalos.h>
18 #include <clib/alib_protos.h>
20 #include <proto/utility.h>
31 #include "scalos_structures.h"
32 #include "functions.h"
33 #include "Variables.h"
35 //----------------------------------------------------------------------------
39 //----------------------------------------------------------------------------
43 struct ScalosSemaphoreList GlobalSemaphoreList
[] =
45 { &WBStartListSema
, "WBStartListSema" },
46 { &LayersSema
, "LayersSema" },
47 { &MenuSema
, "MenuSema" },
48 { &CopyHookSemaphore
, "CopyHookSemaphore" },
49 { &DefIconsSemaphore
, "DefIconsSemaphore" },
50 { &DefIconsCacheSemaphore
, "DefIconsCacheSemaphore" },
51 { &DeleteHookSemaphore
, "DeleteHookSemaphore" },
52 { &FileTypeListSema
, "FileTypeListSema" },
53 { &TextInputHookSemaphore
, "TextInputHookSemaphore" },
54 { &QuitSemaphore
, "QuitSemaphore" },
55 { &CloseWBHookListSemaphore
, "CloseWBHookListSemaphore" },
56 { &ClassListSemaphore
, "ClassListSemaphore" },
57 { &WinListSemaphore
, "WinListSemaphore" },
58 { &DoWaitSemaphore
, "DoWaitSemaphore" },
59 { &PatternSema
, "PatternSema" },
60 { &ParseMenuListSemaphore
, "ParseMenuListSemaphore" },
61 { &ListenerSema
, "ListenerSema" },
62 { &MenuSemaphore
, "MenuSemaphore" },
63 { &AppMenuListSemaphore
, "AppMenuListSemaphore" },
64 { &ThumbnailsCleanupSemaphore
, "ThumbnailsCleanupSemaphore" },
65 { &tteSema
, "tteSema" },
66 { &ClipboardSemaphore
, "ClipboardSemaphore" },
67 { &UndoListListSemaphore
, "UndoListListSemaphore" },
68 { &RedoListListSemaphore
, "RedoListListSemaphore" },
72 //----------------------------------------------------------------------------
76 //----------------------------------------------------------------------------
79 // extension to ScalosAttemptSemaphore()
80 // - prevents nesting when called more than once from same task
81 BOOL
AttemptSemaphoreNoNest(SCALOSSEMAPHORE
*sema
)
83 if (!ScalosAttemptSemaphore(sema
))
86 if (sema
->Sema
.ss_NestCount
> 1)
88 ScalosReleaseSemaphore(sema
);
96 // Try to obtain multiple Semaphores without deadlock
97 // advantages over system ObtainSemaphoreList() :
98 // - supports both exclusive and shared Semaphore access.
99 // - does not use Semaphore Node data.
100 #if !defined(ScaObtainSemaphoreList)
101 void ScaObtainSemaphoreList(ULONG FirstTag
, ...)
104 struct TagItem
*TagList
;
106 va_start(args
, FirstTag
);
108 TagList
= ScalosVTagList(FirstTag
, args
);
111 ScaObtainSemaphoreListA(TagList
);
112 FreeTagItems(TagList
);
117 #endif /* ScaObtainSemaphoreList */
119 void ScaObtainSemaphoreListA(struct TagItem
*OrigTagList
)
124 d1(KPrintF("%s/%s/%ld: START\n", __FILE__
, __FUNC__
, __LINE__
));
127 struct TagItem
*TagList
= OrigTagList
;
129 GlobalSuccess
= TRUE
;
131 d1(kprintf("%s/%s/%ld: Loop START\n", __FILE__
, __FUNC__
, __LINE__
));
134 while (GlobalSuccess
&& (Tag
= NextTagItem(&TagList
)))
138 d1(KPrintF("%s/%s/%ld: Tag=%08lx ti_Tag=%08lx Sema=%08lx\n", __FILE__
, __FUNC__
, __LINE__
, Tag
, Tag
->ti_Tag
, Tag
->ti_Data
));
142 case SCA_SemaphoreExclusive
:
143 Success
= ScalosAttemptSemaphore((SCALOSSEMAPHORE
*) Tag
->ti_Data
);
146 case SCA_SemaphoreShared
:
147 Success
= ScalosAttemptSemaphoreShared((SCALOSSEMAPHORE
*) Tag
->ti_Data
);
151 d1(KPrintF("%s/%s/%ld: Success=%ld\n", __FILE__
, __FUNC__
, __LINE__
, Success
));
155 struct TagItem
*Tag2
, *TagList2
= OrigTagList
;
157 GlobalSuccess
= FALSE
;
159 // Release all previously obtained semaphores
160 while ((Tag2
= NextTagItem(&TagList2
)) && Tag2
!= Tag
)
162 d1(KPrintF("%s/%s/%ld: Tag2=%08lx ti_Tag=%08lx Sema=%08lx\n", __FILE__
, __FUNC__
, __LINE__
, Tag2
, Tag2
->ti_Tag
, Tag2
->ti_Data
));
163 ScalosReleaseSemaphore((SCALOSSEMAPHORE
*) Tag2
->ti_Data
);
166 // wait until Semaphore available
167 d1(kprintf("%s/%s/%ld: before Wait\n", __FILE__
, __FUNC__
, __LINE__
));
170 case SCA_SemaphoreExclusive
:
171 ScalosObtainSemaphore((SCALOSSEMAPHORE
*) Tag
->ti_Data
); // breaks Forbid()
173 case SCA_SemaphoreShared
:
174 ScalosObtainSemaphoreShared((SCALOSSEMAPHORE
*) Tag
->ti_Data
); // breaks Forbid()
178 d1(KPrintF("%s/%s/%ld: after Wait\n", __FILE__
, __FUNC__
, __LINE__
));
182 ScalosReleaseSemaphore((SCALOSSEMAPHORE
*) Tag
->ti_Data
);
186 d1(KPrintF("%s/%s/%ld: GlobalSuccess=%ld\n", __FILE__
, __FUNC__
, __LINE__
, GlobalSuccess
));
187 } while (!GlobalSuccess
);
189 d1(KPrintF("%s/%s/%ld: END\n", __FILE__
, __FUNC__
, __LINE__
));
193 // Try to obtain multiple Semaphores without deadlock
194 // advantages over system ObtainSemaphoreList() :
195 // - supports both exclusive and shared Semaphore access.
196 // - does not use Semaphore Node data.
197 #if !defined(ScaAttemptSemaphoreList)
198 BOOL
ScaAttemptSemaphoreList(ULONG FirstTag
, ...)
201 struct TagItem
*TagList
;
202 BOOL Success
= FALSE
;
204 va_start(args
, FirstTag
);
206 TagList
= ScalosVTagList(FirstTag
, args
);
209 Success
= ScaAttemptSemaphoreListA(TagList
);
210 FreeTagItems(TagList
);
217 #endif /* ScaAttemptSemaphoreListA */
220 BOOL
ScaAttemptSemaphoreListA(struct TagItem
*OriginalTagList
)
222 struct TagItem
*TagList
;
226 d1(kprintf("%s/%s/%ld: START\n", __FILE__
, __FUNC__
, __LINE__
));
228 TagList
= OriginalTagList
;
231 while (Success
&& (Tag
= NextTagItem(&TagList
)))
233 d1(kprintf("%s/%s/%ld: Tag=%08lx ti_Tag=%08lx Sema=%08lx\n", __FILE__
, __FUNC__
, __LINE__
, Tag
, Tag
->ti_Tag
, Tag
->ti_Data
));
237 case SCA_SemaphoreExclusive
:
238 Success
= ScalosAttemptSemaphore((SCALOSSEMAPHORE
*) Tag
->ti_Data
);
241 case SCA_SemaphoreShared
:
242 Success
= ScalosAttemptSemaphoreShared((SCALOSSEMAPHORE
*) Tag
->ti_Data
);
245 case SCA_SemaphoreExclusiveNoNest
:
246 Success
= AttemptSemaphoreNoNest((SCALOSSEMAPHORE
*) Tag
->ti_Data
);
250 d1(kprintf("%s/%s/%ld: Success=%ld\n", __FILE__
, __FUNC__
, __LINE__
, Success
));
254 struct TagItem
*Tag2
, *TagList2
= OriginalTagList
;
256 // Release all previously obtained semaphores
257 while ((Tag2
= NextTagItem(&TagList2
)) && Tag2
!= Tag
)
259 d1(kprintf("%s/%s/%ld: Tag2=%08lx ti_Tag=%08lx Sema=%08lx\n", __FILE__
, __FUNC__
, __LINE__
, Tag2
, Tag2
->ti_Tag
, Tag2
->ti_Data
));
260 ScalosReleaseSemaphore((SCALOSSEMAPHORE
*) Tag2
->ti_Data
);
266 d1(kprintf("%s/%s/%ld: END Success=%ld\n", __FILE__
, __FUNC__
, __LINE__
, Success
));
272 #ifdef DEBUG_SEMAPHORES
274 #undef SignalSemaphore
276 void DebugScalosLockIconListShared(struct internalScaWindowTask
*iwt
,
277 CONST_STRPTR CallingFile
, CONST_STRPTR CallingFunc
, ULONG CallingLine
)
279 d1(KPrintF("%s/%s/%ld: START iwt=%08lx <%s>\n", __FILE__
, __FUNC__
, __LINE__
, iwt
, iwt
->iwt_WinTitle
? iwt
->iwt_WinTitle
: (STRPTR
) ""));
281 // Problem addressed: if the current process already holds an exclusive
282 // lock on the semaphore, ObtainSemaphoreShared() is guaranteed to
283 // create a deadlock.
284 // Solution: is we already own this semaphore exclusively,
285 // ScalosAttemptSemaphore() will succeed.
286 if (DebugScalosAttemptSemaphoreShared(iwt
->iwt_WindowTask
.wt_IconSemaphore
, CallingFile
, CallingFunc
, CallingLine
))
288 if (iwt
->iwt_WindowProcess
== (struct Process
*) FindTask(NULL
))
290 iwt
->iwt_IconListLockedShared
++;
292 d1(kprintf("%s/%s/%ld: END\n", __FILE__
, __FUNC__
, __LINE__
));
295 if (DebugScalosAttemptSemaphore(iwt
->iwt_WindowTask
.wt_IconSemaphore
, CallingFile
, CallingFunc
, CallingLine
))
297 if (iwt
->iwt_WindowProcess
== (struct Process
*) FindTask(NULL
))
299 iwt
->iwt_IconListLockedExclusive
++;
301 d1(kprintf("%s/%s/%ld: END\n", __FILE__
, __FUNC__
, __LINE__
));
305 d1(kprintf("%s/%s/%ld: \n", __FILE__
, __FUNC__
, __LINE__
));
307 DebugScalosObtainSemaphoreShared(iwt
->iwt_WindowTask
.wt_IconSemaphore
, CallingFile
, CallingFunc
, CallingLine
);
309 if (iwt
->iwt_WindowProcess
== (struct Process
*) FindTask(NULL
))
311 iwt
->iwt_IconListLockedShared
++;
314 d1(KPrintF("%s/%s/%ld: END iwt=%08lx <%s>\n", __FILE__
, __FUNC__
, __LINE__
, iwt
, iwt
->iwt_WinTitle
? iwt
->iwt_WinTitle
: (STRPTR
) ""));
318 void DebugScalosLockIconListExclusive(struct internalScaWindowTask
*iwt
,
319 CONST_STRPTR CallingFile
, CONST_STRPTR CallingFunc
, ULONG CallingLine
)
321 d1(KPrintF("%s/%s/%ld: START iwt=%08lx <%s>\n", __FILE__
, __FUNC__
, __LINE__
, iwt
, iwt
->iwt_WinTitle
? iwt
->iwt_WinTitle
: (STRPTR
) ""));
323 if (iwt
->iwt_WindowProcess
== (struct Process
*) FindTask(NULL
)
324 && iwt
->iwt_IconListLockedShared
)
326 // the window process already holds a shared lock on the icon list.
327 // calling ScalosObtainSemaphore now guarantees a deadlock.
330 d1(kprintf("%s/%s/%ld: iwt_IconListLockedShared=%lu iwt_IconListLockedExclusive=%lu\n", \
331 __FILE__
, __FUNC__
, __LINE__
, iwt
->iwt_IconListLockedShared
, iwt
->iwt_IconListLockedExclusive
));
335 // release all shared locks, and establish exclusive lock(s)
336 while (iwt
->iwt_IconListLockedShared
)
338 iwt
->iwt_IconListLockedShared
--;
340 ScalosReleaseSemaphore(iwt
->iwt_WindowTask
.wt_IconSemaphore
);
344 iwt
->iwt_IconListLockedExclusive
++;
345 ScalosObtainSemaphore(iwt
->iwt_WindowTask
.wt_IconSemaphore
);
350 d1(kprintf("%s/%s/%ld: iwt_IconListLockedShared=%lu iwt_IconListLockedExclusive=%lu\n", \
351 __FILE__
, __FUNC__
, __LINE__
, iwt
->iwt_IconListLockedShared
, iwt
->iwt_IconListLockedExclusive
));
354 DebugScalosObtainSemaphore(iwt
->iwt_WindowTask
.wt_IconSemaphore
, CallingFile
, CallingFunc
, CallingLine
);
356 if (iwt
->iwt_WindowProcess
== (struct Process
*) FindTask(NULL
))
358 iwt
->iwt_IconListLockedExclusive
++;
361 d1(KPrintF("%s/%s/%ld: END iwt=%08lx <%s>\n", __FILE__
, __FUNC__
, __LINE__
, iwt
, iwt
->iwt_WinTitle
? iwt
->iwt_WinTitle
: (STRPTR
) ""));
366 struct ScaWindowList
*DebugSCA_LockWindowList(LONG accessmode
,
367 CONST_STRPTR CallingFile
, CONST_STRPTR CallingFunc
, ULONG CallingLine
)
371 case SCA_LockWindowList_Shared
:
372 DebugScalosObtainSemaphoreShared(&WinListSemaphore
,
373 CallingFile
, CallingFunc
, CallingLine
);
375 case SCA_LockWindowList_Exclusiv
:
376 DebugScalosObtainSemaphore(&WinListSemaphore
,
377 CallingFile
, CallingFunc
, CallingLine
);
387 struct ScalosSemaphore
*DebugScalosCreateSemaphore(CONST_STRPTR CallingFile
,
388 CONST_STRPTR CallingFunc
, ULONG CallingLine
)
390 struct ScalosSemaphore
*xsema
;
392 xsema
= AllocVec(sizeof(struct ScalosSemaphore
), MEMF_PUBLIC
| MEMF_CLEAR
);
394 DebugScalosInitSemaphore(xsema
, CallingFile
, CallingFunc
, CallingLine
);
400 void DebugScalosDeleteSemaphore(struct ScalosSemaphore
*xsema
,
401 CONST_STRPTR CallingFile
, CONST_STRPTR CallingFunc
, ULONG CallingLine
)
405 DebugScalosObtainSemaphore(xsema
, CallingFile
, CallingFunc
, CallingLine
);
407 DebugScalosReleaseSemaphore(xsema
, CallingFile
, CallingFunc
, CallingLine
);
414 void DebugScalosInitSemaphore(struct ScalosSemaphore
*xsema
,
415 CONST_STRPTR CallingFile
,
416 CONST_STRPTR CallingFunc
, ULONG CallingLine
)
418 d1(kprintf("%s/%s/%ld: Begin InitSemaphore(%08lx <%s>) Task=%08lx <%s>\n", \
419 CallingFile
, CallingFunc
, CallingLine
, xsema
, FindTask(NULL
), FindTask(NULL
)->tc_Node
.ln_Name
));
421 xsema
->MagicNumber
= DEBUG_SEMAPHORE_MAGIC
;
422 xsema
->SafetyPtr
= &xsema
->Sema
;
424 NewList(&xsema
->OwnerList
);
425 NewList(&xsema
->BidderList
);
426 InitSemaphore(&xsema
->Sema
);
428 d1(kprintf("%s/%s/%ld: End InitSemaphore(%08lx <%s>)\n", \
429 CallingFile
, CallingFunc
, CallingLine
, xsema
));
433 void DebugScalosObtainSemaphore(struct ScalosSemaphore
*xsema
,
434 CONST_STRPTR CallingFile
,
435 CONST_STRPTR CallingFunc
, ULONG CallingLine
)
437 struct DebugSemaOwner
*Owner
;
439 d1(kprintf("%s/%s/%ld: Begin ObtainSemaphore(%08lx <%s>) Task=%08lx <%s>\n", \
440 CallingFile
, CallingFunc
, CallingLine
, xsema
, FindTask(NULL
), FindTask(NULL
)->tc_Node
.ln_Name
));
442 Owner
= AllocVec(sizeof(struct DebugSemaOwner
), MEMF_PUBLIC
);
446 Owner
->OwnMode
= OWNMODE_EXCLUSIVE
;
447 Owner
->FileName
= CallingFile
;
448 Owner
->Func
= CallingFunc
;
449 Owner
->Line
= CallingLine
;
450 Owner
->Proc
= (struct Process
*) FindTask(NULL
);
451 d1(if (Owner
->Proc
->pr_Task
.tc_Node
.ln_Name
&& 0 == strcmp(Owner
->Proc
->pr_Task
.tc_Node
.ln_Name
, "input.device")) \
452 KPrintF("%s/%s/%ld: ObtainSemaphore called from input.device!\n", CallingFile
, CallingFunc
, CallingLine
));
453 AddHead(&xsema
->BidderList
, &Owner
->node
);
457 ObtainSemaphore(&xsema
->Sema
);
462 Remove(&Owner
->node
);
463 AddHead(&xsema
->OwnerList
, &Owner
->node
);
467 d1(kprintf("%s/%s/%ld: End ObtainSemaphore(%08lx <%s>)\n", \
468 CallingFile
, CallingFunc
, CallingLine
, xsema
));
472 void DebugScalosObtainSemaphoreShared(struct ScalosSemaphore
*xsema
,
473 CONST_STRPTR CallingFile
,
474 CONST_STRPTR CallingFunc
, ULONG CallingLine
)
476 struct DebugSemaOwner
*Owner
;
478 d1(kprintf("%s/%s/%ld: Begin ObtainSemaphoreShared(%08lx <%s>) Task=%08lx <%s>\n", \
479 CallingFile
, CallingFunc
, CallingLine
, xsema
, FindTask(NULL
), FindTask(NULL
)->tc_Node
.ln_Name
));
481 Owner
= AllocVec(sizeof(struct DebugSemaOwner
), MEMF_PUBLIC
);
485 Owner
->OwnMode
= OWNMODE_SHARED
;
486 Owner
->FileName
= CallingFile
;
487 Owner
->Func
= CallingFunc
;
488 Owner
->Line
= CallingLine
;
489 Owner
->Proc
= (struct Process
*) FindTask(NULL
);
490 d1(if (Owner
->Proc
->pr_Task
.tc_Node
.ln_Name
&& 0 == strcmp(Owner
->Proc
->pr_Task
.tc_Node
.ln_Name
, "input.device")) \
491 KPrintF("%s/%s/%ld: ObtainSemaphoreShared called from input.device!\n", CallingFile
, CallingFunc
, CallingLine
));
492 AddHead(&xsema
->BidderList
, &Owner
->node
);
496 ObtainSemaphoreShared(&xsema
->Sema
);
501 Remove(&Owner
->node
);
502 AddHead(&xsema
->OwnerList
, &Owner
->node
);
506 d1(kprintf("%s/%s/%ld: End ObtainSemaphoreShared(%08lx <%s>)\n", \
507 CallingFile
, CallingFunc
, CallingLine
, xsema
));
511 void DebugScalosReleaseSemaphore(struct ScalosSemaphore
*xsema
,
512 CONST_STRPTR CallingFile
,
513 CONST_STRPTR CallingFunc
, ULONG CallingLine
)
515 struct DebugSemaOwner
*Owner
;
516 struct Process
*myProc
= (struct Process
*) FindTask(NULL
);
519 d1(kprintf("%s/%s/%ld: Begin ReleaseSemaphore(%08lx) Task=%08lx <%s>\n", \
520 CallingFile
, CallingFunc
, CallingLine
, xsema
, FindTask(NULL
), FindTask(NULL
)->tc_Node
.ln_Name
));
523 for (Owner
= (struct DebugSemaOwner
*) xsema
->OwnerList
.lh_Head
;
524 Owner
!= (struct DebugSemaOwner
*) &xsema
->OwnerList
.lh_Tail
;
525 Owner
= (struct DebugSemaOwner
*) Owner
->node
.ln_Succ
)
527 if (Owner
->Proc
== myProc
)
530 Remove(&Owner
->node
);
539 kprintf("%s/%s/%ld: FAILED ReleaseSemaphore(%08lx) - Task %08lx (%s) never locked this Semaphore!\n", \
540 CallingFile
, CallingFunc
, CallingLine
, xsema
,
541 FindTask(NULL
), FindTask(NULL
)->tc_Node
.ln_Name
);
544 ReleaseSemaphore(&xsema
->Sema
);
546 d1(kprintf("%s/%s/%ld: End ReleaseSemaphore(%08lx)\n", \
547 CallingFile
, CallingFunc
, CallingLine
, xsema
));
551 ULONG
DebugScalosAttemptSemaphore(struct ScalosSemaphore
*xsema
,
552 CONST_STRPTR CallingFile
,
553 CONST_STRPTR CallingFunc
, ULONG CallingLine
)
557 d1(kprintf("%s/%s/%ld: Begin AttemptSemaphore(%08lx) Task=%08lx <%s>\n", \
558 CallingFile
, CallingFunc
, CallingLine
, xsema
, FindTask(NULL
), FindTask(NULL
)->tc_Node
.ln_Name
));
560 Result
= AttemptSemaphore(&xsema
->Sema
);
564 struct DebugSemaOwner
*Owner
;
566 Owner
= AllocVec(sizeof(struct DebugSemaOwner
), MEMF_PUBLIC
);
570 Owner
->OwnMode
= OWNMODE_EXCLUSIVE
;
571 Owner
->FileName
= CallingFile
;
572 Owner
->Func
= CallingFunc
;
573 Owner
->Line
= CallingLine
;
574 Owner
->Proc
= (struct Process
*) FindTask(NULL
);
575 AddHead(&xsema
->OwnerList
, &Owner
->node
);
580 d1(kprintf("%s/%s/%ld: End AttemptSemaphore(%08lx) = %ld\n", \
581 CallingFile
, CallingFunc
, CallingLine
, xsema
, Result
));
587 ULONG
DebugScalosAttemptSemaphoreShared(struct ScalosSemaphore
*xsema
,
588 CONST_STRPTR CallingFile
,
589 CONST_STRPTR CallingFunc
, ULONG CallingLine
)
593 d1(kprintf("%s/%s/%ld: Begin AttemptSemaphoreShared(%08lx) Task=%08lx <%s>\n", \
594 CallingFile
, CallingFunc
, CallingLine
, xsema
, FindTask(NULL
), \
595 FindTask(NULL
)->tc_Node
.ln_Name
? FindTask(NULL
)->tc_Node
.ln_Name
: (char *) ""));
597 Result
= AttemptSemaphoreShared(&xsema
->Sema
);
601 struct DebugSemaOwner
*Owner
;
603 d1(KPrintF("%s/%s/%ld: AttemptSemaphoreShared() succeeded\n", __FILE__
, __FUNC__
, __LINE__
));
605 Owner
= AllocVec(sizeof(struct DebugSemaOwner
), MEMF_PUBLIC
);
609 Owner
->OwnMode
= OWNMODE_SHARED
;
610 Owner
->FileName
= CallingFile
;
611 Owner
->Func
= CallingFunc
;
612 Owner
->Line
= CallingLine
;
613 Owner
->Proc
= (struct Process
*) FindTask(NULL
);
614 AddHead(&xsema
->OwnerList
, &Owner
->node
);
620 Result
= DebugScalosAttemptSemaphore(xsema
, CallingFile
, CallingFunc
, CallingLine
);
623 d1(kprintf("%s/%s/%ld: End AttemptSemaphoreShared(%08lx) = %ld\n", \
624 CallingFile
, CallingFunc
, CallingLine
, xsema
, Result
));
629 #else /* DEBUG_SEMAPHORES */
631 #undef ScalosCreateSemaphore
632 #undef ScalosDeleteSemaphore
633 #undef ScalosInitSemaphore
634 #undef ScalosObtainSemaphore
635 #undef ScalosObtainSemaphoreShared
636 #undef ScalosReleaseSemaphore
637 #undef ScalosAttemptSemaphore
638 #undef ScalosAttemptSemaphoreShared
641 struct ScaWindowList *SCA_LockWindowList(LONG accessmode)
645 case SCA_LockWindowList_Shared:
646 ObtainSemaphoreShared_Debug(&WinListSemaphore,
647 CallingFile, CallingFunc, CallingLine);
649 case SCA_LockWindowList_Exclusiv:
650 ObtainSemaphore_Debug(&WinListSemaphore,
651 CallingFile, CallingFunc, CallingLine);
661 SCALOSSEMAPHORE
*ScalosCreateSemaphore(void)
663 SCALOSSEMAPHORE
*sema
;
665 sema
= AllocVec(sizeof(SCALOSSEMAPHORE
), MEMF_PUBLIC
| MEMF_CLEAR
);
667 ScalosInitSemaphore(sema
);
673 void ScalosDeleteSemaphore(SCALOSSEMAPHORE
*sema
)
677 ScalosObtainSemaphore(sema
);
679 ScalosReleaseSemaphore(sema
);
685 void ScalosInitSemaphore(struct ScalosSemaphore
*xsema
)
687 InitSemaphore(&xsema
->Sema
);
691 void ScalosObtainSemaphore(struct ScalosSemaphore
*xsema
)
693 ObtainSemaphore(&xsema
->Sema
);
697 void ScalosObtainSemaphoreShared(struct ScalosSemaphore
*xsema
)
699 ObtainSemaphoreShared(&xsema
->Sema
);
703 void ScalosReleaseSemaphore(struct ScalosSemaphore
*xsema
)
705 ReleaseSemaphore(&xsema
->Sema
);
709 ULONG
ScalosAttemptSemaphore(struct ScalosSemaphore
*xsema
)
711 return AttemptSemaphore(&xsema
->Sema
);
715 ULONG
ScalosAttemptSemaphoreShared(struct ScalosSemaphore
*xsema
)
717 return AttemptSemaphoreShared(&xsema
->Sema
)
718 || AttemptSemaphore(&xsema
->Sema
);
721 #endif /* DEBUG_SEMAPHORES */