revised some semaphore related methods, primitive functions

This commit is contained in:
hyunghwan.chung 2017-12-11 16:27:53 +00:00
parent 69b2107ed9
commit 9770ddbac6
4 changed files with 60 additions and 133 deletions

View File

@ -218,59 +218,10 @@ method(#class,#abstract) xxx. => method(#class) xxx { self subclassResponsibilit
{
| x |
x := self _wait.
if (x isError) { Exception signal: ('Cannot wait on a semaphore - ' & x asString) }.
if (x signalAction notNil) { x signalAction value: 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
{
| s r |
@ -290,7 +241,7 @@ method(#class,#abstract) xxx. => method(#class) xxx { self subclassResponsibilit
## wait on the semaphore group.
r := self wait.
] on: Exception do: [:ex |
System _unsignal: s.
System unsignal: s.
ex throw
].
@ -307,7 +258,6 @@ method(#class,#abstract) xxx. => method(#class) xxx { self subclassResponsibilit
^r.
}
*)
}
class SemaphoreHeap(Object)

View File

@ -101,70 +101,13 @@ class System(Apex)
## =======================================================================================
method(#class,#primitive) _signal: semaphore afterSecs: secs.
method(#class,#primitive) _signal: semaphore afterSecs: secs nanosecs: nanosecs.
method(#class,#primitive) _signal: semaphore onInOutput: file.
method(#class,#primitive) _signal: semaphore onInput: file.
method(#class,#primitive) _signal: semaphore onOutput: file.
method(#class,#primitive) _signalOnGCFin: 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,#primitive) signal: semaphore afterSecs: secs.
method(#class,#primitive) signal: semaphore afterSecs: secs nanosecs: nanosecs.
method(#class,#primitive) signal: semaphore onInOutput: file.
method(#class,#primitive) signal: semaphore onInput: file.
method(#class,#primitive) signal: semaphore onOutput: file.
method(#class,#primitive) signalOnGCFin: semaphore.
method(#class,#primitive) unsignal: semaphore.
## =======================================================================================
method(#class) sleepForSecs: secs

View File

@ -2098,7 +2098,7 @@ static moo_pfrc_t pf_semaphore_wait (moo_t* moo, moo_ooi_t nargs)
rcv = MOO_STACK_GETRCV(moo, nargs);
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");
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");
return MOO_PF_FAILURE;
}
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);
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.. */
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);
nsec = (nargs == 3? MOO_STACK_GETARG(moo, nargs, 2): MOO_SMOOI_TO_OOP(0));
MOO_PF_CHECK_ARGS(moo, nargs,
moo_iskindof(moo, (moo_oop_t)sem, moo->_semaphore) &&
MOO_OOP_IS_SMOOI(sec) && MOO_OOP_IS_SMOOI(nsec));
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(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) &&
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);
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)
{
@ -2441,13 +2473,17 @@ static moo_pfrc_t pf_system_remove_semaphore (moo_t* moo, moo_ooi_t nargs)
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);
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...
* remove a semaphore from elsewhere registered too */

View File

@ -76,8 +76,8 @@ static moo_pfrc_t pf_open_socket (moo_t* moo, moo_ooi_t nargs)
oops:
if (fd >= 0) close (fd);
MOO_STACK_SETRETTOERROR (moo, nargs, errnum);
return MOO_PF_SUCCESS;
moo_seterrnum (moo, errnum);
return MOO_PF_FAILURE;
}
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);
MOO_STACK_SETRETTORCV (moo, nargs);
}
}
else
{
MOO_STACK_SETRETTOERROR (moo, nargs, MOO_EBADHND);
return MOO_PF_SUCCESS;
}
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)
@ -157,8 +155,8 @@ oops_syserr:
errnum = moo_syserr_to_errnum(errno);
oops:
MOO_STACK_SETRETTOERROR (moo, nargs, errnum);
return MOO_PF_SUCCESS;
moo_seterrnum (moo, errnum);
return MOO_PF_FAILURE;
}
/* ------------------------------------------------------------------------ */