attempted to fix wrong IO semaphore handling over a semaphore group
This commit is contained in:
		| @ -196,7 +196,8 @@ class SemaphoreGroup(Object) | ||||
| 	    first_sem := nil, | ||||
| 	    last_sem := nil, | ||||
| 	    first_sigsem := nil, | ||||
| 	    last_sigsem := nil. | ||||
| 	    last_sigsem := nil, | ||||
| 	    sem_io_count := 0. | ||||
|  | ||||
| (* TODO: good idea to a shortcut way to prohibit a certain method in the heirarchy chain? | ||||
| method(#class,#prohibited) new. | ||||
| @ -220,12 +221,22 @@ method(#class,#abstract) xxx. => method(#class) xxx { self subclassResponsibilit | ||||
| 		if (x isError) { thisProcess primError dump. Exception signal: ('Cannot add a semaphore - ' & thisProcess primError) }. | ||||
| 		^x | ||||
| 	} | ||||
|  | ||||
| 	method removeSemaphore: sem | ||||
| 	{ | ||||
| 		| x | | ||||
| 		x := self _removeSemaphore: sem. | ||||
| 		if (x isError) { thisProcess primError dump. Exception signal: ('Cannot remove a semaphore - ' & thisProcess primError) }. | ||||
| 		^x | ||||
| 	} | ||||
|  | ||||
| 	method wait | ||||
| 	{ | ||||
| 		| r | | ||||
| 		r := self _wait. | ||||
| 		if (r signalAction notNil) { r signalAction value: r }. | ||||
| 		^r | ||||
| 		| x | | ||||
| 		x := self _wait. | ||||
| 		if (x isError) { thisProcess primError dump. Exception signal: ('Cannot remove a semaphore - ' & thisProcess primError) }. | ||||
| 		if (x signalAction notNil) { x signalAction value: x }. | ||||
| 		^x | ||||
| 	} | ||||
|  | ||||
| 	method waitWithTimeout: seconds | ||||
| @ -238,7 +249,7 @@ method(#class,#abstract) xxx. => method(#class) xxx { self subclassResponsibilit | ||||
| 		## grant the partial membership to the internal semaphore. | ||||
| 		## it's partial because it's not added to self.semarr. | ||||
| 		##s _group: self.  | ||||
| 		self _addSemaphore: s. | ||||
| 		self addSemaphore: s. | ||||
|  | ||||
| 		## arrange the processor to notify upon timeout. | ||||
| 		Processor signal: s after: seconds.  | ||||
| @ -253,7 +264,7 @@ method(#class,#abstract) xxx. => method(#class) xxx { self subclassResponsibilit | ||||
|  | ||||
| 		## nullify the membership | ||||
| 		##s _group: nil.  | ||||
| 		self _removeSemaphore: s. | ||||
| 		self removeSemaphore: s. | ||||
|  | ||||
| 		## cancel the notification arrangement in case it didn't time out. | ||||
| 		Processor unsignal: s. | ||||
|  | ||||
| @ -52,29 +52,33 @@ extend Socket | ||||
|  | ||||
| 	method asyncConnect: connectBlock | ||||
| 	{ | ||||
| 		| s1 s2 sg | | ||||
| 		| s1 s2 sg sa | | ||||
|  | ||||
| 		s1 := Semaphore new. | ||||
| 		s2 := Semaphore new. | ||||
|  | ||||
| 		s1 signalAction: [:sem | Processor unsignal: s1. connectBlock value: true]. | ||||
| 		s2 signalAction: [:sem | Processor unsignal: s2. connectBlock value: false]. | ||||
| 		sa := [:sem |  | ||||
| 			Processor unsignal: s1. | ||||
| 			Processor unsignal: s2. | ||||
| 			System removeAsyncSemaphore: s1. | ||||
| 			System removeAsyncSemaphore: s2. | ||||
| 			connectBlock value: (sem == s1) | ||||
| 		]. | ||||
|  | ||||
| 		s1 signalAction: sa. | ||||
| 		s2 signalAction: sa. | ||||
|  | ||||
| ## TODO: unsignal s1 s2, remove them from System when exception occurs. | ||||
| 		Processor signal: s1 onOutput: self.handle. | ||||
| 		Processor signal: s2 after: 10. | ||||
|  | ||||
| 		sg := SemaphoreGroup new. | ||||
| 		sg addSemaphore: s1. | ||||
| 		sg addSemaphore: s2. | ||||
| sg addSemaphore: s1. | ||||
| sg addSemaphore: 10. | ||||
| sg addSemaphore: s1. | ||||
| 		System addAsyncSemaphore: s1. | ||||
| 		System addAsyncSemaphore: s2. | ||||
|  | ||||
| 		if (self _connect(1, 2, 3) isError) | ||||
| 		{ | ||||
| 			Exception signal: 'Cannot connect to 1,2,3'. | ||||
| 		}. | ||||
|  | ||||
| 		sg wait. | ||||
| 	} | ||||
|  | ||||
| 	method asyncRead: readBlock | ||||
|  | ||||
| @ -10,10 +10,28 @@ | ||||
|  | ||||
| class System(Apex) | ||||
| { | ||||
| 	var(#class) asyncsg. | ||||
|  | ||||
| 	method(#class) addAsyncSemaphore: sem | ||||
| 	{ | ||||
| 		^self.asyncsg addSemaphore: sem | ||||
| 	} | ||||
|  | ||||
| 	method(#class) removeAsyncSemaphore: sem | ||||
| 	{ | ||||
| 		^self.asyncsg removeSemaphore: sem | ||||
| 	} | ||||
| 	method(#class) handleAsyncEvent | ||||
| 	{ | ||||
| 		^self.asyncsg wait. | ||||
| 	} | ||||
|  | ||||
| 	method(#class) startup(class_name, method_name) | ||||
| 	{ | ||||
| 		| class ret | | ||||
|  | ||||
| 		self.asyncsg := SemaphoreGroup new. | ||||
|  | ||||
| 		class := System at: class_name. | ||||
| 		if (class isError) | ||||
| 		{ | ||||
| @ -103,7 +121,7 @@ extend System | ||||
| 	##   System logNl: 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'. | ||||
| 	## | ||||
| 	method(#class,#variadic,#primitive) log(level,msg1). | ||||
| 	 | ||||
|  | ||||
| (* | ||||
| TODO: how to pass all variadic arguments to another variadic methods??? | ||||
| 	method(#class,#variadic) logInfo (msg1) | ||||
|  | ||||
		Reference in New Issue
	
	Block a user