revised some semaphore related methods, primitive functions
This commit is contained in:
parent
69b2107ed9
commit
9770ddbac6
@ -218,59 +218,10 @@ method(#class,#abstract) xxx. => method(#class) xxx { self subclassResponsibilit
|
|||||||
{
|
{
|
||||||
| x |
|
| x |
|
||||||
x := self _wait.
|
x := self _wait.
|
||||||
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
|
||||||
}
|
}
|
||||||
|
|
||||||
method _waitWithTimeout: seconds
|
|
||||||
{
|
|
||||||
| s r |
|
|
||||||
|
|
||||||
## create an internal semaphore for timeout notification.
|
|
||||||
s := Semaphore _new.
|
|
||||||
if (s isError) { ^s }.
|
|
||||||
|
|
||||||
## grant the partial membership to the internal semaphore.
|
|
||||||
## it's partial because it's not added to self.semarr.
|
|
||||||
##s _group: self.
|
|
||||||
if ((r := (self addSemaphore: s)) isError) { ^r }.
|
|
||||||
|
|
||||||
## arrange the processor to notify upon timeout.
|
|
||||||
if ((r := (System _signal: s after: seconds)) isError) { ^r }.
|
|
||||||
|
|
||||||
if ((r := self _wait) isError)
|
|
||||||
{
|
|
||||||
System _unsignal: s.
|
|
||||||
^r.
|
|
||||||
}.
|
|
||||||
|
|
||||||
## if the internal semaphore has been signaled,
|
|
||||||
## arrange to return nil to indicate timeout.
|
|
||||||
if (r == s) { r := nil }
|
|
||||||
elsif (r signalAction notNil) { r signalAction value: r }.
|
|
||||||
|
|
||||||
## nullify the membership
|
|
||||||
self _removeSemaphore: s.
|
|
||||||
|
|
||||||
## cancel the notification arrangement in case it didn't time out.
|
|
||||||
System _unsignal: s.
|
|
||||||
|
|
||||||
^r.
|
|
||||||
}
|
|
||||||
|
|
||||||
method waitWithTimeout: seconds
|
|
||||||
{
|
|
||||||
| r |
|
|
||||||
r := self _waitWithTimeout: seconds.
|
|
||||||
if (r isError)
|
|
||||||
{
|
|
||||||
Exception signal: 'Error has occurred...' error: r.
|
|
||||||
}.
|
|
||||||
^r
|
|
||||||
}
|
|
||||||
|
|
||||||
(*
|
|
||||||
method waitWithTimeout: seconds
|
method waitWithTimeout: seconds
|
||||||
{
|
{
|
||||||
| s r |
|
| s r |
|
||||||
@ -290,7 +241,7 @@ method(#class,#abstract) xxx. => method(#class) xxx { self subclassResponsibilit
|
|||||||
## wait on the semaphore group.
|
## wait on the semaphore group.
|
||||||
r := self wait.
|
r := self wait.
|
||||||
] on: Exception do: [:ex |
|
] on: Exception do: [:ex |
|
||||||
System _unsignal: s.
|
System unsignal: s.
|
||||||
ex throw
|
ex throw
|
||||||
].
|
].
|
||||||
|
|
||||||
@ -307,7 +258,6 @@ method(#class,#abstract) xxx. => method(#class) xxx { self subclassResponsibilit
|
|||||||
|
|
||||||
^r.
|
^r.
|
||||||
}
|
}
|
||||||
*)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class SemaphoreHeap(Object)
|
class SemaphoreHeap(Object)
|
||||||
|
@ -101,70 +101,13 @@ class System(Apex)
|
|||||||
|
|
||||||
## =======================================================================================
|
## =======================================================================================
|
||||||
|
|
||||||
method(#class,#primitive) _signal: semaphore afterSecs: secs.
|
method(#class,#primitive) signal: semaphore afterSecs: secs.
|
||||||
method(#class,#primitive) _signal: semaphore afterSecs: secs nanosecs: nanosecs.
|
method(#class,#primitive) signal: semaphore afterSecs: secs nanosecs: nanosecs.
|
||||||
method(#class,#primitive) _signal: semaphore onInOutput: file.
|
method(#class,#primitive) signal: semaphore onInOutput: file.
|
||||||
method(#class,#primitive) _signal: semaphore onInput: file.
|
method(#class,#primitive) signal: semaphore onInput: file.
|
||||||
method(#class,#primitive) _signal: semaphore onOutput: file.
|
method(#class,#primitive) signal: semaphore onOutput: file.
|
||||||
method(#class,#primitive) _signalOnGCFin: semaphore.
|
method(#class,#primitive) signalOnGCFin: semaphore.
|
||||||
method(#class,#primitive) _unsignal: semaphore.
|
method(#class,#primitive) unsignal: semaphore.
|
||||||
|
|
||||||
method(#class) signal: semaphore afterSecs: secs
|
|
||||||
{
|
|
||||||
| x |
|
|
||||||
x := self _signal: semaphore afterSecs: secs.
|
|
||||||
if (x isError) { Exception raise: 'Cannot register a semaphore for signaling - ' & (x asString) }.
|
|
||||||
^x
|
|
||||||
}
|
|
||||||
|
|
||||||
method(#class) signal: semaphore afterSecs: secs nanoSecs: nanosecs
|
|
||||||
{
|
|
||||||
| x |
|
|
||||||
x := self _signal: semaphore afterSecs: secs nanosecs: nanosecs.
|
|
||||||
if (x isError) { Exception raise: 'Cannot register a semaphore for signaling - ' & (x asString) }.
|
|
||||||
^x
|
|
||||||
}
|
|
||||||
|
|
||||||
method(#class) signal: semaphore onInput: file
|
|
||||||
{
|
|
||||||
| x |
|
|
||||||
x := self _signal: semaphore onInput: file.
|
|
||||||
if (x isError) { Exception raise: 'Cannot register a semaphore for signaling - ' & (x asString) }.
|
|
||||||
^x
|
|
||||||
}
|
|
||||||
|
|
||||||
method(#class) signal: semaphore onOutput: file
|
|
||||||
{
|
|
||||||
| x |
|
|
||||||
x := self _signal: semaphore onOutput: file.
|
|
||||||
if (x isError) { Exception raise: 'Cannot register a semaphore for signaling - ' & (x asString) }.
|
|
||||||
^x
|
|
||||||
}
|
|
||||||
|
|
||||||
method(#class) signal: semaphore onInOutput: file
|
|
||||||
{
|
|
||||||
| x |
|
|
||||||
x := self _signal: semaphore onInOutput: file.
|
|
||||||
if (x isError) { Exception raise: 'Cannot register a semaphore for signaling - ' & (x asString) }.
|
|
||||||
^x
|
|
||||||
}
|
|
||||||
|
|
||||||
method(#class) signalOnGCFin: semaphore
|
|
||||||
{
|
|
||||||
| x |
|
|
||||||
x := self _signalOnGCFin: semaphore.
|
|
||||||
if (x isError) { Exception raise: 'Cannot register a semaphore for GC finalization - ' & (x asString) }.
|
|
||||||
^x
|
|
||||||
}
|
|
||||||
|
|
||||||
method(#class) unsignal: semaphore
|
|
||||||
{
|
|
||||||
| x |
|
|
||||||
x := self _unsignal: semaphore.
|
|
||||||
if (x isError) { Exception raise: 'Cannot deregister a semaphore from signaling ' & (x asString) }.
|
|
||||||
^x
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
## =======================================================================================
|
## =======================================================================================
|
||||||
method(#class) sleepForSecs: secs
|
method(#class) sleepForSecs: secs
|
||||||
|
@ -2098,7 +2098,7 @@ static moo_pfrc_t pf_semaphore_wait (moo_t* moo, moo_ooi_t nargs)
|
|||||||
rcv = MOO_STACK_GETRCV(moo, nargs);
|
rcv = MOO_STACK_GETRCV(moo, nargs);
|
||||||
MOO_PF_CHECK_RCV (moo, moo_iskindof(moo, rcv, moo->_semaphore));
|
MOO_PF_CHECK_RCV (moo, moo_iskindof(moo, rcv, moo->_semaphore));
|
||||||
|
|
||||||
if (!can_await_semaphore (moo, (moo_oop_semaphore_t)rcv))
|
if (!can_await_semaphore(moo, (moo_oop_semaphore_t)rcv))
|
||||||
{
|
{
|
||||||
moo_seterrbfmt (moo, MOO_EPERM, "not allowed to wait on a semaphore that belongs to a semaphore group");
|
moo_seterrbfmt (moo, MOO_EPERM, "not allowed to wait on a semaphore that belongs to a semaphore group");
|
||||||
return MOO_PF_FAILURE;
|
return MOO_PF_FAILURE;
|
||||||
@ -2165,6 +2165,7 @@ static moo_pfrc_t pf_semaphore_group_add_semaphore (moo_t* moo, moo_ooi_t nargs)
|
|||||||
moo_seterrbfmt (moo, MOO_EPERM, "not allowed to relocate a semaphore to a different group");
|
moo_seterrbfmt (moo, MOO_EPERM, "not allowed to relocate a semaphore to a different group");
|
||||||
return MOO_PF_FAILURE;
|
return MOO_PF_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
return MOO_PF_SUCCESS;
|
return MOO_PF_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2296,7 +2297,12 @@ static moo_pfrc_t pf_system_add_gcfin_semaphore (moo_t* moo, moo_ooi_t nargs)
|
|||||||
|
|
||||||
MOO_ASSERT (moo, nargs == 1);
|
MOO_ASSERT (moo, nargs == 1);
|
||||||
sem = (moo_oop_semaphore_t)MOO_STACK_GETARG(moo, nargs, 0);
|
sem = (moo_oop_semaphore_t)MOO_STACK_GETARG(moo, nargs, 0);
|
||||||
MOO_PF_CHECK_ARGS (moo, nargs, moo_iskindof(moo, (moo_oop_t)sem, moo->_semaphore));
|
|
||||||
|
if (!moo_iskindof(moo, (moo_oop_t)sem, moo->_semaphore))
|
||||||
|
{
|
||||||
|
moo_seterrbfmt (moo, MOO_EINVAL, "parameter not a kind of semaphore - %O", sem);
|
||||||
|
return MOO_PF_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
/* TODO: no overwriting.. */
|
/* TODO: no overwriting.. */
|
||||||
moo->sem_gcfin = sem;
|
moo->sem_gcfin = sem;
|
||||||
@ -2320,9 +2326,23 @@ static moo_pfrc_t pf_system_add_timed_semaphore (moo_t* moo, moo_ooi_t nargs)
|
|||||||
sec = MOO_STACK_GETARG(moo, nargs, 1);
|
sec = MOO_STACK_GETARG(moo, nargs, 1);
|
||||||
nsec = (nargs == 3? MOO_STACK_GETARG(moo, nargs, 2): MOO_SMOOI_TO_OOP(0));
|
nsec = (nargs == 3? MOO_STACK_GETARG(moo, nargs, 2): MOO_SMOOI_TO_OOP(0));
|
||||||
|
|
||||||
MOO_PF_CHECK_ARGS(moo, nargs,
|
if (!moo_iskindof(moo, (moo_oop_t)sem, moo->_semaphore))
|
||||||
moo_iskindof(moo, (moo_oop_t)sem, moo->_semaphore) &&
|
{
|
||||||
MOO_OOP_IS_SMOOI(sec) && MOO_OOP_IS_SMOOI(nsec));
|
moo_seterrbfmt (moo, MOO_EINVAL, "parameter not a kind of semaphore - %O", sem);
|
||||||
|
return MOO_PF_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!MOO_OOP_IS_SMOOI(sec))
|
||||||
|
{
|
||||||
|
moo_seterrbfmt (moo, MOO_EINVAL, "invalid second - %O", sec);
|
||||||
|
return MOO_PF_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!MOO_OOP_IS_SMOOI(sec))
|
||||||
|
{
|
||||||
|
moo_seterrbfmt (moo, MOO_EINVAL, "invalid nanosecond - %O", nsec);
|
||||||
|
return MOO_PF_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
if (MOO_OOP_IS_SMOOI(sem->heap_index) &&
|
if (MOO_OOP_IS_SMOOI(sem->heap_index) &&
|
||||||
sem->heap_index != MOO_SMOOI_TO_OOP(-1))
|
sem->heap_index != MOO_SMOOI_TO_OOP(-1))
|
||||||
@ -2374,7 +2394,19 @@ static moo_pfrc_t __system_add_io_semaphore (moo_t* moo, moo_ooi_t nargs, moo_oo
|
|||||||
fd = MOO_STACK_GETARG(moo, nargs, 1);
|
fd = MOO_STACK_GETARG(moo, nargs, 1);
|
||||||
sem = (moo_oop_semaphore_t)MOO_STACK_GETARG(moo, nargs, 0);
|
sem = (moo_oop_semaphore_t)MOO_STACK_GETARG(moo, nargs, 0);
|
||||||
|
|
||||||
MOO_PF_CHECK_ARGS (moo, nargs, MOO_CLASSOF(moo,sem) == moo->_semaphore && MOO_OOP_IS_SMOOI(fd));
|
|
||||||
|
if (!moo_iskindof(moo, (moo_oop_t)sem, moo->_semaphore))
|
||||||
|
{
|
||||||
|
moo_seterrbfmt (moo, MOO_EINVAL, "parameter not a kind of semaphore - %O", sem);
|
||||||
|
return MOO_PF_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!MOO_OOP_IS_SMOOI(fd))
|
||||||
|
{
|
||||||
|
moo_seterrbfmt (moo, MOO_EINVAL, "IO handle not a small integer - %O", fd);
|
||||||
|
return MOO_PF_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (MOO_OOP_IS_SMOOI(sem->io_index) && sem->io_index != MOO_SMOOI_TO_OOP(-1) && sem->io_handle == fd)
|
if (MOO_OOP_IS_SMOOI(sem->io_index) && sem->io_index != MOO_SMOOI_TO_OOP(-1) && sem->io_handle == fd)
|
||||||
{
|
{
|
||||||
@ -2441,12 +2473,16 @@ static moo_pfrc_t pf_system_remove_semaphore (moo_t* moo, moo_ooi_t nargs)
|
|||||||
|
|
||||||
moo_oop_semaphore_t sem;
|
moo_oop_semaphore_t sem;
|
||||||
|
|
||||||
/*MOO_PF_CHECK_RCV (moo, MOO_STACK_GETRCV(moo, nargs) == (moo_oop_t)moo->processor);*/
|
/*MOO_PF_CHECK_RCV (moo, MOO_STACK_GETRCV(moo, nargs) == (moo_oop_t)moo->system);*/
|
||||||
|
|
||||||
MOO_ASSERT (moo, nargs == 1);
|
MOO_ASSERT (moo, nargs == 1);
|
||||||
|
|
||||||
sem = (moo_oop_semaphore_t)MOO_STACK_GETARG(moo, nargs, 0);
|
sem = (moo_oop_semaphore_t)MOO_STACK_GETARG(moo, nargs, 0);
|
||||||
MOO_PF_CHECK_ARGS(moo, nargs, MOO_CLASSOF(moo,sem) == moo->_semaphore);
|
if (!moo_iskindof(moo, (moo_oop_t)sem, moo->_semaphore))
|
||||||
|
{
|
||||||
|
moo_seterrbfmt (moo, MOO_EINVAL, "parameter not a kind of semaphore - %O", sem);
|
||||||
|
return MOO_PF_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
/* TODO: remove a semaphore from IO handler if it's registered...
|
/* TODO: remove a semaphore from IO handler if it's registered...
|
||||||
* remove a semaphore from elsewhere registered too */
|
* remove a semaphore from elsewhere registered too */
|
||||||
|
@ -76,8 +76,8 @@ static moo_pfrc_t pf_open_socket (moo_t* moo, moo_ooi_t nargs)
|
|||||||
|
|
||||||
oops:
|
oops:
|
||||||
if (fd >= 0) close (fd);
|
if (fd >= 0) close (fd);
|
||||||
MOO_STACK_SETRETTOERROR (moo, nargs, errnum);
|
moo_seterrnum (moo, errnum);
|
||||||
return MOO_PF_SUCCESS;
|
return MOO_PF_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static moo_pfrc_t pf_close_socket (moo_t* moo, moo_ooi_t nargs)
|
static moo_pfrc_t pf_close_socket (moo_t* moo, moo_ooi_t nargs)
|
||||||
@ -104,13 +104,11 @@ static moo_pfrc_t pf_close_socket (moo_t* moo, moo_ooi_t nargs)
|
|||||||
sck->handle = MOO_SMOOI_TO_OOP(-1);
|
sck->handle = MOO_SMOOI_TO_OOP(-1);
|
||||||
MOO_STACK_SETRETTORCV (moo, nargs);
|
MOO_STACK_SETRETTORCV (moo, nargs);
|
||||||
}
|
}
|
||||||
}
|
return MOO_PF_SUCCESS;
|
||||||
else
|
|
||||||
{
|
|
||||||
MOO_STACK_SETRETTOERROR (moo, nargs, MOO_EBADHND);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return MOO_PF_SUCCESS;
|
moo_seterrbfmt (moo, MOO_EBADHND, "bad socket handle - %O", sck->handle);
|
||||||
|
return MOO_PF_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static moo_pfrc_t pf_connect (moo_t* moo, moo_ooi_t nargs)
|
static moo_pfrc_t pf_connect (moo_t* moo, moo_ooi_t nargs)
|
||||||
@ -157,8 +155,8 @@ oops_syserr:
|
|||||||
errnum = moo_syserr_to_errnum(errno);
|
errnum = moo_syserr_to_errnum(errno);
|
||||||
|
|
||||||
oops:
|
oops:
|
||||||
MOO_STACK_SETRETTOERROR (moo, nargs, errnum);
|
moo_seterrnum (moo, errnum);
|
||||||
return MOO_PF_SUCCESS;
|
return MOO_PF_FAILURE;
|
||||||
}
|
}
|
||||||
/* ------------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------------ */
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user