mirror of
https://gitlab.com/embeddable-common-lisp/ecl.git
synced 2026-01-15 13:52:16 -08:00
Update description of ecl_wait_on().
This commit is contained in:
parent
323822457c
commit
d6f806af2c
1 changed files with 12 additions and 9 deletions
|
|
@ -191,14 +191,20 @@ ecl_wait_on_timed(cl_env_ptr env, cl_object (*condition)(cl_env_ptr, cl_object),
|
|||
* the condition are
|
||||
* - The first process to arrive to the queue,
|
||||
* - Each process which is awoken.
|
||||
* - The first process after the list of awoken processes.
|
||||
*
|
||||
* The idea is that this will ensure some fairness when unblocking the
|
||||
* processes, which is important for abstractions such as mutexes or
|
||||
* semaphores, where we want equal sharing of resources among processes.
|
||||
*
|
||||
* This also implies that the waiting processes depend on others to signal
|
||||
* when to check for a condition, which is whenever the fields that are
|
||||
* checked for change.
|
||||
* when to check for a condition. This happens in two situations
|
||||
* - External code that changes the fields of the queue object
|
||||
* must signal ecl_wakeup_waiters() (See mutex.d, semaphore.d, etc)
|
||||
* - When a process exits ecl_wait_on() it always resignals the next
|
||||
* process in the queue, because a condition may be satisfied more
|
||||
* than once (for instance when a semaphore is changed, more than
|
||||
* one process may be released)
|
||||
*
|
||||
* The critical part of this algorithm is the fact that processes
|
||||
* communicating the change of conditions may do so before, during or
|
||||
|
|
@ -259,12 +265,9 @@ ecl_wait_on(cl_env_ptr env, cl_object (*condition)(cl_env_ptr, cl_object), cl_ob
|
|||
} while (Null(output = condition(the_env, o)));
|
||||
}
|
||||
} CL_UNWIND_PROTECT_EXIT {
|
||||
/* 4) If we are aborting and we are the first waiting
|
||||
* process in the queue, it may happen that our wakeup
|
||||
* signal got lost. We must wake up another process
|
||||
* after removing ourselves. */
|
||||
/* 4) At this point we wrap up. We remove ourselves
|
||||
from the queue and restore signals, which were */
|
||||
* from the queue and unblock the lisp interrupt
|
||||
* signal. Note that we recover the cons for later use.*/
|
||||
cl_object firstone = o->queue.list;
|
||||
wait_queue_delete(the_env, o, own_process);
|
||||
own_process->process.waiting_for = Cnil;
|
||||
|
|
@ -282,8 +285,8 @@ ecl_wait_on(cl_env_ptr env, cl_object (*condition)(cl_env_ptr, cl_object), cl_ob
|
|||
ecl_wakeup_waiters(the_env, o, 0, ECL_WAKEUP_ONE);
|
||||
}
|
||||
|
||||
/* 7) Restoring signals is done last, to ensure that
|
||||
all cleanup steps are performed. */
|
||||
/* 6) Restoring signals is done last, to ensure that
|
||||
* all cleanup steps are performed. */
|
||||
pthread_sigmask(SIG_SETMASK, &original, NULL);
|
||||
} CL_UNWIND_PROTECT_END;
|
||||
return output;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue