simplified SemaphoreGroup by switching a semaphore array to a semaphore list.
added some copy methods to Array
This commit is contained in:
		| @ -64,17 +64,54 @@ class(#pointer) Array(Collection) | ||||
|  | ||||
| 	method last | ||||
| 	{ | ||||
| 		^self at: (self basicSize - 1). | ||||
| 		^self at: (self size - 1). | ||||
| 	} | ||||
|  | ||||
| 	method do: aBlock | ||||
| 	{ | ||||
| 		0 priorTo: (self basicSize) do: [:i | aBlock value: (self at: i)]. | ||||
| 		0 priorTo: (self size) do: [:i | aBlock value: (self at: i)]. | ||||
| 	} | ||||
|  | ||||
| 	method copy: anArray | ||||
| 	{ | ||||
| 		0 priorTo: (anArray basicSize) do: [:i | self at: i put: (anArray at: i) ]. | ||||
| 		0 priorTo: (anArray size) do: [:i | self at: i put: (anArray at: i) ]. | ||||
| 	} | ||||
|  | ||||
| 	method copy: anArray from: start to: end | ||||
| 	{ | ||||
| 		## copy elements from an array 'anArray' starting from  | ||||
| 		## the index 'start' to the index 'end'. | ||||
|  | ||||
| 		| s i ss | | ||||
|  | ||||
| (* | ||||
| 		s := anArray size. | ||||
|  | ||||
| 		if (start < 0) { start := 0 } | ||||
| 		elsif (start >= s) { start := s - 1 }. | ||||
|  | ||||
| 		if (end < 0) { end := 0 } | ||||
| 		elsif (end >= s) { end := s - 1 }. | ||||
| *) | ||||
| 		i := 0. | ||||
| 		ss := self size. | ||||
| 		while (start <= end) | ||||
| 		{ | ||||
| 			if (i >= ss) { break }. | ||||
| 			self at: i put: (anArray at: start). | ||||
| 			i := i + 1. | ||||
| 			start := start + 1. | ||||
| 		}. | ||||
| 	} | ||||
|  | ||||
| 	method copyFrom: start to: end | ||||
| 	{ | ||||
| 		## returns a copy of the receiver starting from the element  | ||||
| 		## at index 'start' to the element at index 'end'. | ||||
|  | ||||
| 		| newsz | | ||||
| 		newsz := end - start + 1. | ||||
| 		^(self class new: newsz) copy: self from: start to: end | ||||
| 	} | ||||
|  | ||||
| 	method = anArray | ||||
|  | ||||
| @ -60,8 +60,11 @@ class Semaphore(Object) | ||||
| 	    ioHandle      := nil, | ||||
| 	    ioMask        :=   0. | ||||
|  | ||||
| 	var (#get,#set) signalAction := nil. | ||||
| 	var(#get,#set) _group := nil. | ||||
| 	var(#get,#set) signalAction := nil. | ||||
|  | ||||
| 	var(#get,#set) _group := nil,  | ||||
| 	               _grm_next := nil, | ||||
| 	               _grm_prev := nil. | ||||
|  | ||||
| 	## ================================================================== | ||||
|  | ||||
| @ -198,69 +201,30 @@ class SemaphoreGroup(Object) | ||||
| { | ||||
| 	var waiting_head  := nil, | ||||
| 	    waiting_tail  := nil, | ||||
| 	    size := 0, | ||||
| 	    pos := 0, | ||||
| 	    semarr := nil. | ||||
| 	    first_sem := nil, | ||||
| 	    last_sem := nil, | ||||
| 	    first_sigsem := nil, | ||||
| 	    last_sigsem := nil. | ||||
|  | ||||
| (* TODO: good idea to a shortcut way to prohibit a certain method in the heirarchy chain? | ||||
|  | ||||
| method(#class,#prohibited) new. | ||||
| method(#class,#prohibited) new: size. | ||||
| method(#class,#abstract) xxx. => method(#class) xxx { self subclassResponsibility: #xxxx } | ||||
| *) | ||||
|  | ||||
| (* | ||||
| 	method(#class) new { self messageProhibited: #new } | ||||
| 	method(#class) new: size { self messageProhibited: #new: } | ||||
| *) | ||||
|  | ||||
| 	method(#class,#variadic) with() | ||||
| 	{ | ||||
| 		| i x arr sem | | ||||
|  | ||||
| 		i := 0. | ||||
| 		x := thisContext vargCount. | ||||
|  | ||||
| 		arr := Array new: x. | ||||
| 		while (i < x) | ||||
| 		{ | ||||
| 			sem := thisContext vargAt: i. | ||||
| 			if (sem _group notNil) | ||||
| 			{ | ||||
| 				System.Exception signal: 'Cannot add a semaphore in a group to another group' | ||||
| 			}. | ||||
|  | ||||
| 			arr at: i put: sem. | ||||
| 			i := i + 1. | ||||
| 		}. | ||||
|  | ||||
| 		^self basicNew initialize: arr. | ||||
| 	} | ||||
|  | ||||
| 	method initialize | ||||
| 	{ | ||||
| 		self.semarr := Array new: 10. | ||||
| 	} | ||||
|  | ||||
| 	method initialize: arr | ||||
| 	{ | ||||
| 		| i sem | | ||||
| 		self.size := arr size. | ||||
| 		self.semarr := arr. | ||||
|  | ||||
| 		i := 0. | ||||
| 		while (i < self.size) | ||||
| 		{ | ||||
| 			sem := self.semarr at: i. | ||||
| 			sem _group: self. | ||||
| 			i := i + 1. | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	method(#primitive) _addSemaphore: sem. | ||||
| 	method(#primitive) _removeSemaphore: sem. | ||||
| 	method(#primitive) _wait. | ||||
|  | ||||
| 	method wait | ||||
| 	{ | ||||
| 		| r | | ||||
| 		r := self wait. | ||||
| 		r := self _wait. | ||||
| 		if (r signalAction notNil) { r signalAction value: r }. | ||||
| 		^r | ||||
| 	} | ||||
| @ -274,7 +238,8 @@ 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.  | ||||
| 		##s _group: self.  | ||||
| 		self _addSemaphore: s. | ||||
|  | ||||
| 		## arrange the processor to notify upon timeout. | ||||
| 		Processor signal: s after: seconds.  | ||||
| @ -288,7 +253,8 @@ method(#class,#abstract) xxx. => method(#class) xxx { self subclassResponsibilit | ||||
| 		elsif (r signalAction notNil) { r signalAction value: r }. | ||||
|  | ||||
| 		## nullify the membership | ||||
| 		s _group: nil.  | ||||
| 		##s _group: nil.  | ||||
| 		self _removeSemaphore: s. | ||||
|  | ||||
| 		## cancel the notification arrangement in case it didn't time out. | ||||
| 		Processor unsignal: s. | ||||
|  | ||||
		Reference in New Issue
	
	Block a user