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

View File

@ -945,7 +945,7 @@ static int skip_comment (moo_t* moo)
GET_CHAR_TO (moo, c);
if (c == MOO_UCI_EOF) goto unterminated;
if (c == '*') goto check_rparen;
if (c == '*') goto check_rparen; /* got another * after * */
if (c == ')')
{
GET_CHAR (moo); /* keep the first meaningful character in lxc */

View File

@ -889,7 +889,13 @@ static MOO_INLINE moo_oop_t await_semaphore_group (moo_t* moo, moo_oop_semaphore
/* link the suspended process to the semaphore group's process list */
chain_into_semaphore (moo, proc, (moo_oop_semaphore_t)semgrp);
MOO_ASSERT (moo, semgrp->waiting.last == proc);
/*if (MOO_OOP_TO_SMOOI(semgrp->io_index) >= 0) moo->semgrp_io_wait_count++;*/
if (MOO_OOP_TO_SMOOI(semgrp->sem_io_count) >= 0)
{
/* there might be more than 1 IO semaphores in the group
* but i increment moo->sem_io_wait_count by 1 only */
moo->sem_io_wait_count++;
}
/* the current process will get suspended after the caller (mostly a
* a primitive function handler) is over as it's added to a suspened
@ -1092,6 +1098,17 @@ static int add_to_sem_io (moo_t* moo, moo_oop_semaphore_t sem)
sem->io_index = MOO_SMOOI_TO_OOP(-1);
moo->sem_io_count--;
}
else
{
/* update the number of IO semaphores in a group if necessary */
if ((moo_oop_t)sem->group != moo->_nil)
{
moo_ooi_t count;
count = MOO_OOP_TO_SMOOI(sem->group->sem_io_count);
count++;
sem->group->sem_io_count = MOO_SMOOI_TO_OOP(count);
}
}
return n;
}
@ -1121,8 +1138,16 @@ static int delete_from_sem_io (moo_t* moo, moo_ooi_t index)
MOO_DEBUG2 (moo, "Deleted IO semaphore at index %zd on handle %zd\n", index, MOO_OOP_TO_SMOOI(sem->io_handle));
sem->io_index = MOO_SMOOI_TO_OOP(-1);
moo->sem_io_count--;
if ((moo_oop_t)sem->group != moo->_nil)
{
moo_ooi_t count;
count = MOO_OOP_TO_SMOOI(sem->group->sem_io_count);
MOO_ASSERT (moo, count > 0);
count--;
sem->group->sem_io_count = MOO_SMOOI_TO_OOP(count);
}
if (/*moo->sem_io_count > 0 &&*/ index != moo->sem_io_count)
{
moo_oop_semaphore_t lastsem;
@ -2557,6 +2582,15 @@ static moo_pfrc_t pf_semaphore_group_add_semaphore (moo_t* moo, moo_ooi_t nargs)
sems_idx = MOO_OOP_TO_SMOOI(sem->count) > 0? MOO_SEMAPHORE_GROUP_SEMS_SIG: MOO_SEMAPHORE_GROUP_SEMS_UNSIG;
MOO_APPEND_TO_OOP_LIST (moo, &rcv->sems[sems_idx], moo_oop_semaphore_t, sem, grm);
sem->group = rcv;
if (MOO_OOP_TO_SMOOI(sem->io_index) >=0)
{
moo_ooi_t count;
count = MOO_OOP_TO_SMOOI(rcv->sem_io_count);
count++;
rcv->sem_io_count = MOO_SMOOI_TO_OOP(count);
}
MOO_STACK_SETRETTORCV (moo, nargs);
}
else if (sem->group == rcv)
@ -2593,6 +2627,14 @@ static moo_pfrc_t pf_semaphore_group_remove_semaphore (moo_t* moo, moo_ooi_t nar
sem->grm.next = (moo_oop_semaphore_t)moo->_nil;
sem->group = (moo_oop_semaphore_group_t)moo->_nil;
if (MOO_OOP_TO_SMOOI(sem->io_index) >=0)
{
moo_ooi_t count;
count = MOO_OOP_TO_SMOOI(rcv->sem_io_count);
count--;
rcv->sem_io_count = MOO_SMOOI_TO_OOP(count);
}
MOO_STACK_SETRETTORCV (moo, nargs);
}
else

View File

@ -76,6 +76,7 @@ struct kernel_class_info_t
moo_oow_t len;
moo_ooch_t name[20];
int class_flags;
int class_num_classvars;
int class_spec_named_instvars;
int class_spec_flags;
@ -105,6 +106,7 @@ static kernel_class_info_t kernel_classes[] =
0,
0,
0,
0,
MOO_OBJ_TYPE_OOP,
MOO_OFFSETOF(moo_t, _apex) },
@ -113,13 +115,15 @@ static kernel_class_info_t kernel_classes[] =
0,
0,
0,
0,
MOO_OBJ_TYPE_OOP,
MOO_OFFSETOF(moo_t, _undefined_object) },
#define KCI_CLASS 2
#define KCI_CLASS 2 /* index to the Class entry in this table */
{ 5,
{ 'C','l','a','s','s' },
MOO_CLASS_SELFSPEC_FLAG_LIMITED,
0,
MOO_CLASS_NAMED_INSTVARS,
1,
MOO_OBJ_TYPE_OOP,
@ -130,6 +134,7 @@ static kernel_class_info_t kernel_classes[] =
0,
0,
0,
0,
MOO_OBJ_TYPE_OOP,
MOO_OFFSETOF(moo_t, _object) },
@ -137,6 +142,7 @@ static kernel_class_info_t kernel_classes[] =
{ 'S','t','r','i','n','g' },
0,
0,
0,
MOO_CLASS_SPEC_FLAG_INDEXED,
MOO_OBJ_TYPE_CHAR,
MOO_OFFSETOF(moo_t, _string) },
@ -145,6 +151,7 @@ static kernel_class_info_t kernel_classes[] =
{ 'S','y','m','b','o','l' },
MOO_CLASS_SELFSPEC_FLAG_FINAL | MOO_CLASS_SELFSPEC_FLAG_LIMITED,
0,
0,
MOO_CLASS_SPEC_FLAG_INDEXED | MOO_CLASS_SPEC_FLAG_IMMUTABLE,
MOO_OBJ_TYPE_CHAR,
MOO_OFFSETOF(moo_t, _symbol) },
@ -153,6 +160,7 @@ static kernel_class_info_t kernel_classes[] =
{ 'A','r','r','a','y' },
0,
0,
0,
MOO_CLASS_SPEC_FLAG_INDEXED,
MOO_OBJ_TYPE_OOP,
MOO_OFFSETOF(moo_t, _array) },
@ -161,6 +169,7 @@ static kernel_class_info_t kernel_classes[] =
{ 'B','y','t','e','A','r','r','a','y' },
0,
0,
0,
MOO_CLASS_SPEC_FLAG_INDEXED,
MOO_OBJ_TYPE_BYTE,
MOO_OFFSETOF(moo_t, _byte_array) },
@ -168,6 +177,7 @@ static kernel_class_info_t kernel_classes[] =
{ 9,
{ 'S','y','m','b','o','l','S','e','t' },
0,
0,
MOO_DIC_NAMED_INSTVARS,
0,
MOO_OBJ_TYPE_OOP,
@ -176,6 +186,7 @@ static kernel_class_info_t kernel_classes[] =
{ 10,
{ 'D','i','c','t','i','o','n','a','r','y' },
0,
0,
MOO_DIC_NAMED_INSTVARS,
0,
MOO_OBJ_TYPE_OOP,
@ -184,6 +195,7 @@ static kernel_class_info_t kernel_classes[] =
{ 9,
{ 'N','a','m','e','s','p','a','c','e' },
MOO_CLASS_SELFSPEC_FLAG_LIMITED,
0,
MOO_NSDIC_NAMED_INSTVARS,
0,
MOO_OBJ_TYPE_OOP,
@ -192,6 +204,7 @@ static kernel_class_info_t kernel_classes[] =
{ 14,
{ 'P','o','o','l','D','i','c','t','i','o','n','a','r','y' },
0,
0,
MOO_DIC_NAMED_INSTVARS,
0,
MOO_OBJ_TYPE_OOP,
@ -200,6 +213,7 @@ static kernel_class_info_t kernel_classes[] =
{ 16,
{ 'M','e','t','h','o','d','D','i','c','t','i','o','n','a','r','y' },
0,
0,
MOO_DIC_NAMED_INSTVARS,
0,
MOO_OBJ_TYPE_OOP,
@ -208,6 +222,7 @@ static kernel_class_info_t kernel_classes[] =
{ 14,
{ 'C','o','m','p','i','l','e','d','M','e','t','h','o','d' },
0,
0,
MOO_METHOD_NAMED_INSTVARS,
MOO_CLASS_SPEC_FLAG_INDEXED,
MOO_OBJ_TYPE_OOP,
@ -217,6 +232,7 @@ static kernel_class_info_t kernel_classes[] =
{ 11,
{ 'A','s','s','o','c','i','a','t','i','o','n' },
0,
0,
MOO_ASSOCIATION_NAMED_INSTVARS,
0,
MOO_OBJ_TYPE_OOP,
@ -225,6 +241,7 @@ static kernel_class_info_t kernel_classes[] =
{ 13,
{ 'M','e','t','h','o','d','C','o','n','t','e','x','t' },
MOO_CLASS_SELFSPEC_FLAG_FINAL | MOO_CLASS_SELFSPEC_FLAG_LIMITED,
0,
MOO_CONTEXT_NAMED_INSTVARS,
MOO_CLASS_SPEC_FLAG_INDEXED,
MOO_OBJ_TYPE_OOP,
@ -233,6 +250,7 @@ static kernel_class_info_t kernel_classes[] =
{ 12,
{ 'B','l','o','c','k','C','o','n','t','e','x','t' },
MOO_CLASS_SELFSPEC_FLAG_FINAL | MOO_CLASS_SELFSPEC_FLAG_LIMITED,
0,
MOO_CONTEXT_NAMED_INSTVARS,
MOO_CLASS_SPEC_FLAG_INDEXED,
MOO_OBJ_TYPE_OOP,
@ -241,6 +259,7 @@ static kernel_class_info_t kernel_classes[] =
{ 7,
{ 'P','r','o','c','e','s','s' },
MOO_CLASS_SELFSPEC_FLAG_FINAL | MOO_CLASS_SELFSPEC_FLAG_LIMITED,
0,
MOO_PROCESS_NAMED_INSTVARS,
MOO_CLASS_SPEC_FLAG_INDEXED,
MOO_OBJ_TYPE_OOP,
@ -249,6 +268,7 @@ static kernel_class_info_t kernel_classes[] =
{ 9,
{ 'S','e','m','a','p','h','o','r','e' },
0,
0,
MOO_SEMAPHORE_NAMED_INSTVARS,
0,
MOO_OBJ_TYPE_OOP,
@ -257,6 +277,7 @@ static kernel_class_info_t kernel_classes[] =
{ 14,
{ 'S','e','m','a','p','h','o','r','e','G','r','o','u','p' },
0,
0,
MOO_SEMAPHORE_GROUP_NAMED_INSTVARS,
0,
MOO_OBJ_TYPE_OOP,
@ -265,6 +286,7 @@ static kernel_class_info_t kernel_classes[] =
{ 16,
{ 'P','r','o','c','e','s','s','S','c','h','e','d','u','l','e','r' },
MOO_CLASS_SELFSPEC_FLAG_FINAL | MOO_CLASS_SELFSPEC_FLAG_LIMITED,
0,
MOO_PROCESS_SCHEDULER_NAMED_INSTVARS,
0,
MOO_OBJ_TYPE_OOP,
@ -275,6 +297,7 @@ static kernel_class_info_t kernel_classes[] =
MOO_CLASS_SELFSPEC_FLAG_LIMITED,
0,
0,
0,
MOO_OBJ_TYPE_OOP,
MOO_OFFSETOF(moo_t, _error_class) },
@ -283,6 +306,7 @@ static kernel_class_info_t kernel_classes[] =
0,
0,
0,
0,
MOO_OBJ_TYPE_OOP,
MOO_OFFSETOF(moo_t, _true_class) },
@ -291,6 +315,7 @@ static kernel_class_info_t kernel_classes[] =
0,
0,
0,
0,
MOO_OBJ_TYPE_OOP,
MOO_OFFSETOF(moo_t, _false_class) },
@ -302,6 +327,7 @@ static kernel_class_info_t kernel_classes[] =
MOO_CLASS_SELFSPEC_FLAG_LIMITED,
0,
0,
0,
MOO_OBJ_TYPE_OOP,
MOO_OFFSETOF(moo_t, _character) },
@ -310,6 +336,7 @@ static kernel_class_info_t kernel_classes[] =
MOO_CLASS_SELFSPEC_FLAG_LIMITED,
0,
0,
0,
MOO_OBJ_TYPE_OOP,
MOO_OFFSETOF(moo_t, _small_integer) },
@ -317,6 +344,7 @@ static kernel_class_info_t kernel_classes[] =
{ 'L','a','r','g','e','P','o','s','i','t','i','v','e','I','n','t','e','g','e','r' },
0,
0,
0,
MOO_CLASS_SPEC_FLAG_INDEXED | MOO_CLASS_SPEC_FLAG_IMMUTABLE,
MOO_OBJ_TYPE_LIWORD,
MOO_OFFSETOF(moo_t, _large_positive_integer) },
@ -325,6 +353,7 @@ static kernel_class_info_t kernel_classes[] =
{ 'L','a','r','g','e','N','e','g','a','t','i','v','e','I','n','t','e','g','e','r' },
0,
0,
0,
MOO_CLASS_SPEC_FLAG_INDEXED | MOO_CLASS_SPEC_FLAG_IMMUTABLE,
MOO_OBJ_TYPE_LIWORD,
MOO_OFFSETOF(moo_t, _large_negative_integer) },
@ -334,12 +363,14 @@ static kernel_class_info_t kernel_classes[] =
0,
0,
0,
0,
MOO_OBJ_TYPE_OOP,
MOO_OFFSETOF(moo_t, _small_pointer) },
{ 6,
{ 'S','y','s','t','e','m' },
0,
1, /* asyncsg */
0,
0,
MOO_OBJ_TYPE_OOP,
@ -386,7 +417,8 @@ static int ignite_1 (moo_t* moo)
* which are actually class variables.
* -------------------------------------------------------------- */
moo->_class = alloc_kernel_class (
moo, kernel_classes[KCI_CLASS].class_flags, 0,
moo, kernel_classes[KCI_CLASS].class_flags,
kernel_classes[KCI_CLASS].class_num_classvars,
MOO_CLASS_SPEC_MAKE (kernel_classes[KCI_CLASS].class_spec_named_instvars,
kernel_classes[KCI_CLASS].class_spec_flags,
kernel_classes[KCI_CLASS].class_spec_indexed_type));
@ -402,7 +434,8 @@ static int ignite_1 (moo_t* moo)
if (i == KCI_CLASS) continue; /* skip Class as it's created above */
tmp = alloc_kernel_class (
moo, kernel_classes[i].class_flags, 0,
moo, kernel_classes[i].class_flags,
kernel_classes[i].class_num_classvars,
MOO_CLASS_SPEC_MAKE (kernel_classes[i].class_spec_named_instvars,
kernel_classes[i].class_spec_flags,
kernel_classes[i].class_spec_indexed_type));

View File

@ -754,7 +754,7 @@ typedef struct moo_process_t* moo_oop_process_t;
typedef struct moo_semaphore_t moo_semaphore_t;
typedef struct moo_semaphore_t* moo_oop_semaphore_t;
#define MOO_SEMAPHORE_GROUP_NAMED_INSTVARS 6
#define MOO_SEMAPHORE_GROUP_NAMED_INSTVARS 7
typedef struct moo_semaphore_group_t moo_semaphore_group_t;
typedef struct moo_semaphore_group_t* moo_oop_semaphore_group_t;
@ -846,6 +846,8 @@ struct moo_semaphore_group_t
moo_oop_semaphore_t first;
moo_oop_semaphore_t last;
} sems[2]; /* sems[0] - unsignaled semaphores, sems[1] - signaled semaphores */
moo_oop_t sem_io_count;
};
#define MOO_PROCESS_SCHEDULER_NAMED_INSTVARS 9