attempted to fix wrong IO semaphore handling over a semaphore group

This commit is contained in:
hyunghwan.chung
2017-10-31 07:13:22 +00:00
parent 9ae1b99b43
commit 5ae166c1d4
7 changed files with 141 additions and 31 deletions

View File

@ -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.

View File

@ -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

View File

@ -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)