disallowed semaphore removal from a group when a process is waiting for the semaphore to be signaled
This commit is contained in:
		| @ -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 |  | ||||||
|  *   |  *   | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user