disallowed semaphore removal from a group when a process is waiting for the semaphore to be signaled
This commit is contained in:
parent
f7272c00fb
commit
27c2c5b404
@ -218,7 +218,7 @@ method(#class,#abstract) xxx. => method(#class) xxx { self subclassResponsibilit
|
|||||||
{
|
{
|
||||||
| x |
|
| x |
|
||||||
x := self _addSemaphore: sem.
|
x := self _addSemaphore: sem.
|
||||||
if (x isError) { thisProcess primError dump. Exception signal: ('Cannot add a semaphore - ' & thisProcess primError) }.
|
if (x isError) { Exception signal: ('Cannot add a semaphore - ' & x asString) }.
|
||||||
^x
|
^x
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -226,7 +226,7 @@ method(#class,#abstract) xxx. => method(#class) xxx { self subclassResponsibilit
|
|||||||
{
|
{
|
||||||
| x |
|
| x |
|
||||||
x := self _removeSemaphore: sem.
|
x := self _removeSemaphore: sem.
|
||||||
if (x isError) { thisProcess primError dump. Exception signal: ('Cannot remove a semaphore - ' & thisProcess primError) }.
|
if (x isError) { Exception signal: ('Cannot remove a semaphore - ' & x asString) }.
|
||||||
^x
|
^x
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -234,7 +234,7 @@ method(#class,#abstract) xxx. => method(#class) xxx { self subclassResponsibilit
|
|||||||
{
|
{
|
||||||
| x |
|
| x |
|
||||||
x := self _wait.
|
x := self _wait.
|
||||||
if (x isError) { thisProcess primError dump. Exception signal: ('Cannot wait on a semaphore - ' & thisProcess primError) }.
|
if (x isError) { Exception signal: ('Cannot wait on a semaphore - ' & x asString) }.
|
||||||
if (x signalAction notNil) { x signalAction value: x }.
|
if (x signalAction notNil) { x signalAction value: x }.
|
||||||
^x
|
^x
|
||||||
}
|
}
|
||||||
|
@ -33,6 +33,7 @@ class MyObject(Object)
|
|||||||
s3 := Semaphore new.
|
s3 := Semaphore new.
|
||||||
|
|
||||||
sg := SemaphoreGroup new.
|
sg := SemaphoreGroup new.
|
||||||
|
|
||||||
sg addSemaphore: s1.
|
sg addSemaphore: s1.
|
||||||
sg addSemaphore: s2.
|
sg addSemaphore: s2.
|
||||||
sg addSemaphore: s3.
|
sg addSemaphore: s3.
|
||||||
|
@ -816,7 +816,7 @@ static MOO_INLINE void await_semaphore (moo_t* moo, moo_oop_semaphore_t sem)
|
|||||||
count = MOO_OOP_TO_SMOOI(sem->count);
|
count = MOO_OOP_TO_SMOOI(sem->count);
|
||||||
if (count > 0)
|
if (count > 0)
|
||||||
{
|
{
|
||||||
/* it's already signalled */
|
/* it's already signaled */
|
||||||
count--;
|
count--;
|
||||||
sem->count = MOO_SMOOI_TO_OOP(count);
|
sem->count = MOO_SMOOI_TO_OOP(count);
|
||||||
|
|
||||||
@ -881,7 +881,7 @@ static MOO_INLINE moo_oop_t await_semaphore_group (moo_t* moo, moo_oop_semaphore
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* no semaphores have been signaled. suspend the current process
|
/* no semaphores have been signaled. suspend the current process
|
||||||
* until the at least one of them is signaled */
|
* until at least one of them is signaled */
|
||||||
proc = moo->processor->active;
|
proc = moo->processor->active;
|
||||||
|
|
||||||
/* suspend the active process */
|
/* suspend the active process */
|
||||||
@ -2622,6 +2622,25 @@ static moo_pfrc_t pf_semaphore_group_remove_semaphore (moo_t* moo, moo_ooi_t nar
|
|||||||
if (sem->group == rcv)
|
if (sem->group == rcv)
|
||||||
{
|
{
|
||||||
int sems_idx;
|
int sems_idx;
|
||||||
|
|
||||||
|
if ((moo_oop_t)rcv->waiting.first != moo->_nil)
|
||||||
|
{
|
||||||
|
/* there is a process waiting on this semaphore group.
|
||||||
|
* i don't allow a semaphore to be removed from the group.
|
||||||
|
* i want to dodge potential problems arising when removal is allowed.
|
||||||
|
*
|
||||||
|
* for instance, consider this psuedo code.
|
||||||
|
* sg addSemaphore: s
|
||||||
|
* [ sg wait ] fork.
|
||||||
|
* [ sg wait ] fork.
|
||||||
|
* [ sg wait ] fork.
|
||||||
|
* sg removeSemaphore: s.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
MOO_STACK_SETRETTOERROR (moo, nargs, MOO_EPERM);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
sems_idx = MOO_OOP_TO_SMOOI(sem->count) > 0? MOO_SEMAPHORE_GROUP_SEMS_SIG: MOO_SEMAPHORE_GROUP_SEMS_UNSIG;
|
sems_idx = MOO_OOP_TO_SMOOI(sem->count) > 0? MOO_SEMAPHORE_GROUP_SEMS_SIG: MOO_SEMAPHORE_GROUP_SEMS_UNSIG;
|
||||||
MOO_DELETE_FROM_OOP_LIST (moo, &rcv->sems[sems_idx], sem, grm);
|
MOO_DELETE_FROM_OOP_LIST (moo, &rcv->sems[sems_idx], sem, grm);
|
||||||
sem->grm.prev = (moo_oop_semaphore_t)moo->_nil;
|
sem->grm.prev = (moo_oop_semaphore_t)moo->_nil;
|
||||||
@ -2632,6 +2651,7 @@ static moo_pfrc_t pf_semaphore_group_remove_semaphore (moo_t* moo, moo_ooi_t nar
|
|||||||
{
|
{
|
||||||
moo_ooi_t count;
|
moo_ooi_t count;
|
||||||
count = MOO_OOP_TO_SMOOI(rcv->sem_io_count);
|
count = MOO_OOP_TO_SMOOI(rcv->sem_io_count);
|
||||||
|
MOO_ASSERT (moo, count > 0);
|
||||||
count--;
|
count--;
|
||||||
rcv->sem_io_count = MOO_SMOOI_TO_OOP(count);
|
rcv->sem_io_count = MOO_SMOOI_TO_OOP(count);
|
||||||
}
|
}
|
||||||
@ -2644,6 +2664,7 @@ static moo_pfrc_t pf_semaphore_group_remove_semaphore (moo_t* moo, moo_ooi_t nar
|
|||||||
MOO_STACK_SETRETTOERROR (moo, nargs, MOO_EPERM);
|
MOO_STACK_SETRETTOERROR (moo, nargs, MOO_EPERM);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
done:
|
||||||
return MOO_PF_SUCCESS;
|
return MOO_PF_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2666,7 +2687,7 @@ static moo_pfrc_t pf_semaphore_group_wait (moo_t* moo, moo_ooi_t nargs)
|
|||||||
sem = await_semaphore_group (moo, (moo_oop_semaphore_group_t)rcv);
|
sem = await_semaphore_group (moo, (moo_oop_semaphore_group_t)rcv);
|
||||||
if (sem != moo->_nil)
|
if (sem != moo->_nil)
|
||||||
{
|
{
|
||||||
/* there was a singaled semaphore. the active process won't get
|
/* there was a signaled semaphore. the active process won't get
|
||||||
* suspended. change the return value of the current process
|
* suspended. change the return value of the current process
|
||||||
* forcibly to the signaled semaphore */
|
* forcibly to the signaled semaphore */
|
||||||
MOO_STACK_SETTOP (moo, sem);
|
MOO_STACK_SETTOP (moo, sem);
|
||||||
@ -4957,7 +4978,7 @@ static MOO_INLINE int switch_process_if_needed (moo_t* moo)
|
|||||||
if (moo->sem_gcfin_sigreq)
|
if (moo->sem_gcfin_sigreq)
|
||||||
{
|
{
|
||||||
signal_sem_gcfin:
|
signal_sem_gcfin:
|
||||||
MOO_LOG0 (moo, MOO_LOG_IC | MOO_LOG_DEBUG, "Signalled GCFIN semaphore\n");
|
MOO_LOG0 (moo, MOO_LOG_IC | MOO_LOG_DEBUG, "Signaled GCFIN semaphore\n");
|
||||||
proc = signal_semaphore (moo, moo->sem_gcfin);
|
proc = signal_semaphore (moo, moo->sem_gcfin);
|
||||||
|
|
||||||
if (moo->processor->active == moo->nil_process && (moo_oop_t)proc != moo->_nil)
|
if (moo->processor->active == moo->nil_process && (moo_oop_t)proc != moo->_nil)
|
||||||
@ -4998,7 +5019,7 @@ static MOO_INLINE int switch_process_if_needed (moo_t* moo)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
MOO_LOG3 (moo, MOO_LOG_IC | MOO_LOG_DEBUG,
|
MOO_LOG3 (moo, MOO_LOG_IC | MOO_LOG_DEBUG,
|
||||||
"Signalled GCFIN semaphore without gcfin signal request - total - %zd runnable/running - %zd suspended - %zd\n",
|
"Signaled GCFIN semaphore without gcfin signal request - total - %zd runnable/running - %zd suspended - %zd\n",
|
||||||
MOO_OOP_TO_SMOOI(moo->processor->total_count), MOO_OOP_TO_SMOOI(moo->processor->runnable.count), MOO_OOP_TO_SMOOI(moo->processor->suspended.count));
|
MOO_OOP_TO_SMOOI(moo->processor->total_count), MOO_OOP_TO_SMOOI(moo->processor->runnable.count), MOO_OOP_TO_SMOOI(moo->processor->suspended.count));
|
||||||
proc = signal_semaphore (moo, moo->sem_gcfin);
|
proc = signal_semaphore (moo, moo->sem_gcfin);
|
||||||
if ((moo_oop_t)proc != moo->_nil)
|
if ((moo_oop_t)proc != moo->_nil)
|
||||||
|
@ -28,7 +28,7 @@
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Stix .....................
|
* Apex......................
|
||||||
* ^ ^ ^ : .......
|
* ^ ^ ^ : .......
|
||||||
* | | | v v :
|
* | | | v v :
|
||||||
* | | +------------------- Class .....
|
* | | +------------------- Class .....
|
||||||
@ -41,7 +41,7 @@
|
|||||||
*
|
*
|
||||||
* The class hierarchy is roughly as follows:
|
* The class hierarchy is roughly as follows:
|
||||||
*
|
*
|
||||||
* Stix
|
* Apex
|
||||||
* Class
|
* Class
|
||||||
* NilObject
|
* NilObject
|
||||||
* Object
|
* Object
|
||||||
@ -66,8 +66,7 @@
|
|||||||
* LargePositiveInteger
|
* LargePositiveInteger
|
||||||
* LargeNegativeInteger
|
* LargeNegativeInteger
|
||||||
*
|
*
|
||||||
* Stix has no instance variables.
|
* Apex has no instance variables.
|
||||||
* Stix has 1 class variable: Sysdic
|
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user