docs/random/wtay/poll-timeout: Quick braindump for a possible (not totally verified) atomic case.

Original commit message from CVS:
* docs/random/wtay/poll-timeout:
Quick braindump for a possible (not totally verified) atomic case.
This commit is contained in:
Wim Taymans 2008-11-12 12:45:46 +00:00
parent 681e4d01c8
commit 162b2a6a3c
2 changed files with 75 additions and 2 deletions

View file

@ -1,3 +1,8 @@
2008-11-12 Wim Taymans <wim.taymans@collabora.co.uk>
* docs/random/wtay/poll-timeout:
Quick braindump for a possible (not totally verified) atomic case.
2008-11-12 Sebastian Dröge <sebastian.droege@collabora.co.uk> 2008-11-12 Sebastian Dröge <sebastian.droege@collabora.co.uk>
* gst/gstregistrybinary.c: (gst_registry_binary_write_chunk), * gst/gstregistrybinary.c: (gst_registry_binary_write_chunk),

View file

@ -1,3 +1,6 @@
WITH LOCK
*********
create clock id: create clock id:
id->state = OK; id->state = OK;
@ -42,10 +45,75 @@ waiting for id:
unschedule id: unschedule id:
lock lock
/* when it leaves the poll, it'll detect the unscheduled. */
id->state = unscheduled;
/* if it's busy waiting in poll, write to the fd */ /* if it's busy waiting in poll, write to the fd */
if (id->state == busy) { if (id->state == busy) {
write (fd) write (fd)
} }
/* when it leaves the poll, it'll detect the unscheduled. */
id->state = unscheduled;
unlock unlock
ATOMIC
******
create clock id:
id->state = OK;
waiting for id:
/* once state changes to != OK, the id cannot be used anymore */
while (g_atomic_int_compare_and_exchange (&id->state, OK, BUSY) {
ret = gstpoll (timeout);
/* two things can happen here, either the entry is BUSY or UNSCHEDULED,
* first check if it was busy. */
if (g_atomic_int_compare_and_exchange (&id->state, BUSY, OK) {
/* we got unscheduled, see if it was because we timed out or some other
* id got unscheduled */
if (ret != 0) {
lock
/* some other id got unlocked */
/* wait until it reads the fd and signals us */
while (waiters)
cond_wait ()
unlock
}
else {
/* we timed out update the status. */
id->state = OK | EARLY;
break;
}
}
else if (g_atomic_int_compare_and_exchange (&id->state, UNSCHEDULED, OK) {
/* id became unscheduled, read the fd and broadcast */
lock
read (fd)
waiters--
cond_broadcast ()
unlock
id->state = UNSCHEDULED;
break;
}
}
return id->state;
unschedule id:
if (g_atomic_int_compare_and_exchange (&id->state, BUSY, UNSCHEDULED) {
/* if it's busy waiting in poll, write to the fd */
lock
waiters++
write (fd)
unlock
}
else {
/* was not waiting, just mark unscheduled */
g_atomic_int_set (id->state, UNSCHEDULED);
}