mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-09-08 13:18:52 +00:00
123 lines
2.6 KiB
Text
123 lines
2.6 KiB
Text
WITH LOCK
|
|
*********
|
|
|
|
create clock id:
|
|
|
|
id->state = OK;
|
|
|
|
|
|
waiting for id:
|
|
|
|
lock
|
|
/* once unscheduled, the id cannot be used anymore */
|
|
while (id->state != unscheduled) {
|
|
id->state = busy;
|
|
unlock
|
|
|
|
ret = gstpoll (timeout);
|
|
|
|
lock
|
|
if (id->state == unscheduled) {
|
|
/* id became unscheduled, read the fd and broadcast */
|
|
read (fd)
|
|
cond_broadcast ()
|
|
}
|
|
else {
|
|
if (ret != 0) {
|
|
/* some other id got unlocked */
|
|
/* mark ourselves as EARLY, we release the lock and we could be
|
|
* unscheduled ourselves but we don't want the unscheduling thread
|
|
* to write on the fd */
|
|
id->state = EARLY;
|
|
/* wait until it reads the fd and signals us */
|
|
cond_wait ()
|
|
}
|
|
else {
|
|
/* we timed out */
|
|
id->state = OK | EARLY;
|
|
}
|
|
}
|
|
}
|
|
unlock
|
|
return id->state;
|
|
|
|
|
|
unschedule id:
|
|
|
|
lock
|
|
/* if it's busy waiting in poll, write to the fd */
|
|
if (id->state == busy) {
|
|
write (fd)
|
|
}
|
|
/* when it leaves the poll, it'll detect the unscheduled. */
|
|
id->state = unscheduled;
|
|
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) {
|
|
if (g_atomic_int_get (&waiters) > 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_get (&id->state) == UNSCHEDULED) {
|
|
/* id became unscheduled, read the fd and broadcast */
|
|
lock
|
|
read (fd)
|
|
g_atomic_int_dec (&waiters);
|
|
cond_broadcast ()
|
|
unlock
|
|
break;
|
|
}
|
|
else {
|
|
g_assert_not_reached ();
|
|
}
|
|
}
|
|
|
|
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
|
|
g_atomic_int_inc (&waiters)
|
|
write (fd)
|
|
unlock
|
|
}
|
|
else {
|
|
/* was not waiting, just mark unscheduled */
|
|
g_atomic_int_set (id->state, UNSCHEDULED);
|
|
}
|