File: locking_rules.txt

package info (click to toggle)
mplayerplug-in 3.31%2Bmain-1
  • links: PTS
  • area: main
  • in suites: etch, etch-m68k
  • size: 1,376 kB
  • ctags: 845
  • sloc: cpp: 12,138; ansic: 1,951; makefile: 162; sh: 112
file content (88 lines) | stat: -rw-r--r-- 2,809 bytes parent folder | download | duplicates (2)
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
LOCKING RULES AND INVARIANTS:

invariants:

meaning of js_state are the following: 

JS_STATE_UNDEFINED  means no player thread.
JS_STATE_BUFFERING means thread is waiting on the condition variable.
JS_STATE_INITIALIZING means thread was just started, but did not start
         waiting on the condition variable yet.
JS_STATE_TRANSITIONING means player thread is about to close the
      connection and accessing control pipe is unsafe
      (or control == 0).
JS_STATE_PLAYING etc have the obvious meanings. 

Locking Rules:

(0) Rule: when player thread is dead (i.e. in shut after the 
    pthread_join), no locking is needed (and no locking rules apply).. 

(1) Rule: all read or write access to instance->js_state (in all threads) must 
     be protected by control_mutex.

(2) Rule: all read and write access to the playlist (i.e. td->list) must
    be protected by playlist_mutex. 

(3) Rule: No thread may block with control_mutex held.

(4) Rule: If one needs to acquire both playlist_mutex and control_mutex,
    playlist_mutex must be acquired first. Doing it in the other order
    will deadlock.

(5) Rule: all access to instance->control (from both threads) must be protected
    by control_mutex. 

(6) Exception to last rule: when js_state == JS_STATE_TRANSITIONING
    player thread does not need locks for instance->control, 
    but access by main thread is prohibuted.



(7) Rule: In the player thread, any code which looks like

    pthread_mutex_lock(&some_lock);

    .... do stuff ....

    pthread_mutex_unlock(&some_lock);
  
    where the ... do stuff ... includes a cancellation point, 
    
    must be protected by pthread_cleanup_push(pthread_mutex_unlock, some_lock)
    and pthread_cleanup_pop(0)
    
    Recall that pthread_test_cancel(), pthread_cond_wait() and any
    blocking system call/libc function is a cancellation point. 



(8) Rule: instance->player is owned by the player thread. The only time
    main thread can access it is when the player thread is already
    dead (e.g. in shut after the pthread_join).


(9) Corollary to above rules: 
    All calls to sendCommand have to protected by control_mutex. Also
    in player thread, calls to sendCommand have to be
    protected by cleanup_push/cleanup_pop as well. 

(10) Rule: Player thread may be started if there isn't one currently
     (i.e. js_state == JS_STATE_UNDEFINED).  To start player thread, must do: 

     pthread_lock(&control_mutex);
     pthread_create(....)
     js_state = JS_STATE_INITIALIZING;
     pthread_unlock(&control_mutex);

(11) Rule: to signal player thread, must use the signalPlayerThread()
      function. 

(12) Rule: to kill player thread, must do:
 
        pthread_cancel(&player_thread);
        pthread_join(&player_thread);
        js_state = JS_STATE_UNDEFINED;