File: poll-timeout

package info (click to toggle)
gstreamer1.0 1.28.0-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 15,604 kB
  • sloc: ansic: 203,072; python: 1,985; sh: 566; lex: 188; lisp: 154; java: 81; makefile: 59; cpp: 58; perl: 46
file content (123 lines) | stat: -rw-r--r-- 2,679 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
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);
   }