File: ThreadsafeX11Guard.h

package info (click to toggle)
kwave 0.7.2-5
  • links: PTS
  • area: main
  • in suites: sarge
  • size: 9,048 kB
  • ctags: 4,906
  • sloc: cpp: 31,275; ansic: 13,111; sh: 9,511; perl: 2,724; makefile: 786; asm: 145
file content (121 lines) | stat: -rw-r--r-- 3,893 bytes parent folder | download
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
/***************************************************************************
    ThreadsafeX11Guard.h -  guard for using X11 from a worker thread
			     -------------------
    begin                : Sun Jun 03 2001
    copyright            : (C) 2001 by Thomas Eschenbacher
    email                : Thomas.Eschenbacher@gmx.de
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/

#ifndef _THREADSAFE_X11_GUARD_H_
#define _THREADSAFE_X11_GUARD_H_

#include "config.h"
#include <qobject.h>

#include "mt/SignalProxy.h"
#include "mt/Semaphore.h"
#include "mt/TSS_Object.h"
#include "mt/Mutex.h"

/**
 * @class ThreadsafeX11Guard
 * If a thread other than the program's main thread wants to access X11,
 * e.g. for doing some drawing or showing windows or dialog boxes, the
 * main thread has to be suspended until X11 output is done. This is
 * needed because <b>X11 currently is not threadsafe!</b>.
 *
 * @note This guard can be used multiple times in different contexts, it
 *       is able to handle recursion within the same thread. So you can
 *       use it as often as you want without having the danger of a
 *       deadlock.
 *
 * @warning Doing X11 output without this using this guard class normally
 *          leads to incomprehensible program crahes like bus errors or
 *          segmentation faults.
 */
class ThreadsafeX11Guard: public QObject, public TSS_Object
{
    Q_OBJECT

public:
    /** Constructor */
    ThreadsafeX11Guard();

    /** Destructor */
    virtual ~ThreadsafeX11Guard();

private slots:

    /**
     * This slot is called in the context of the X11 thread and locks
     * X11 while the worker thread is active. The handshake process
     * with the worker thread is done via some semaphores.
     * @see m_sem_x11_locked
     * @see m_sem_x11_done
     * @see m_sem_x11_unlocked
     */
    void lockX11();

private:

    /** The global/unique lock for X11 */
    static Mutex m_lock_X11;

    /**
     * Internal lock for access to the X11 subsystem
     */
    static Mutex m_internal_lock;

    /**
     * The mutex for entering/leaving a protected area, used in our
     * constructor and destructor. Protects m_recursion_level and
     * m_pid_owner
     */
    static Mutex m_lock_recursion;

    /** thread id of the thread that is currently holding the X11 lock */
    static pthread_t m_pid_owner;

    /** thread id of the X11 thread (main thread) */
    static pthread_t m_pid_x11;

    /** counter for recursive X11 locks. */
    static unsigned int m_recursion_level;

    /**
     * Semaphore set by lockX11() to signal that X11 has been locked and
     * the X11 thread will be suspended.
     */
    Semaphore m_sem_x11_locked;

    /**
     * Semaphore set by the worker thread to signal the X11 thread that
     * is currently suspended in lockX11() that it can continue and
     * release X11 again.
     */
    Semaphore m_sem_x11_done;

    /**
     * Semaphore set by lockX11() to signal that X11 has been unlocked
     * again and the X11 thread is active again.
     */
    Semaphore m_sem_x11_unlocked;

    /**
     * The SignalProxy activates the X11 thread and lets it enter lockX11()
     */
    SignalProxy<void> m_spx_X11_request;

};

#endif /* _THREADSAFE_X11_GUARD_H_ */