1
/****************************************************************************
3
** Copyright (C) 1992-2005 Trolltech AS. All rights reserved.
5
** This file is part of the embedded classes of the Qt Toolkit.
7
** This file may be distributed under the terms of the Q Public License
8
** as defined by Trolltech AS of Norway and appearing in the file
9
** LICENSE.QPL included in the packaging of this file.
11
** This file may be distributed and/or modified under the terms of the
12
** GNU General Public License version 2 as published by the Free Software
13
** Foundation and appearing in the file LICENSE.GPL included in the
14
** packaging of this file.
16
** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
17
** information about Qt Commercial License Agreements.
18
** See http://www.trolltech.com/qpl/ for QPL licensing information.
19
** See http://www.trolltech.com/gpl/ for GPL licensing information.
21
** Contact info@trolltech.com if any conditions of this licensing are
24
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
25
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
27
****************************************************************************/
31
#ifndef QT_NO_QWS_MULTIPROCESS
34
#include <sys/types.h>
35
#if defined(Q_OS_DARWIN)
36
#define Q_NO_SEMAPHORE
41
#if defined(__GNU_LIBRARY__) && !defined(_SEM_SEMUN_UNDEFINED) \
42
|| defined(Q_OS_FREEBSD) || defined(Q_OS_OPENBSD) || defined(Q_OS_NETBSD) || defined(Q_OS_BSDI)
43
/* union semun is defined by including <sys/sem.h> */
45
/* according to X/OPEN we have to define it ourselves */
47
int val; /* value for SETVAL */
48
struct semid_ds *buf; /* buffer for IPC_STAT, IPC_SET */
49
unsigned short *array; /* array for GETALL, SETALL */
58
#define MAX_LOCKS 200 // maximum simultaneous read locks
74
\class QLock qlock_p.h
75
\brief The QLock class is a wrapper for a System V shared semaphore.
82
It is used by Qt/Embedded for synchronizing access to the graphics
83
card and shared memory region between processes.
94
\fn QLock::QLock(const QString &filename, char id, bool create)
96
Creates a lock. \a filename is the file path of the Unix-domain
97
socket the Qt/Embedded client is using. \a id is the name of the
98
particular lock to be created on that socket. If \a create is true
99
the lock is to be created (as the Qt/Embedded server does); if \a
100
create is false the lock should exist already (as the Qt/Embedded
104
QLock::QLock(const QString &filename, char id, bool create)
106
#ifndef QT_NO_QWS_MULTIPROCESS
107
data = new QLockData;
109
#ifdef Q_NO_SEMAPHORE
110
data->file = QString(filename+id).toLocal8Bit().constData();
111
for(int x = 0; x < 2; x++) {
112
data->id = open(data->file, O_RDWR | (x ? O_CREAT : 0), S_IRWXU);
113
if(data->id != -1 || !create) {
119
key_t semkey = ftok(filename.toLocal8Bit().constData(), id);
120
data->id = semget(semkey,0,0);
121
data->owned = create;
123
semun arg; arg.val = 0;
125
semctl(data->id,0,IPC_RMID,arg);
126
data->id = semget(semkey,1,IPC_CREAT|0600);
128
semctl(data->id,0,SETVAL,arg);
131
if (data->id == -1) {
132
qWarning() << "Cannot" << (create ? "create" : "get") << "semaphore"
133
<< filename << "'" << id << "'";
134
qDebug() << "Error" << errno << strerror(errno);
147
#ifndef QT_NO_QWS_MULTIPROCESS
150
#ifdef Q_NO_SEMAPHORE
158
semun arg; arg.val = 0;
159
semctl(data->id, 0, IPC_RMID, arg);
167
\fn bool QLock::isValid() const
169
Returns true if the lock constructor was successful; returns false if
170
the lock could not be created or was not available to connect to.
173
bool QLock::isValid() const
175
#ifndef QT_NO_QWS_MULTIPROCESS
176
return (data->id != -1);
183
Locks the semaphore with a lock of type \a t. Locks can either be
184
\c Read or \c Write. If a lock is \c Read, attempts by other
185
processes to obtain \c Read locks will succeed, and \c Write
186
attempts will block until the lock is unlocked. If locked as \c
187
Write, all attempts to lock by other processes will block until
188
the lock is unlocked. Locks are stacked: i.e. a given QLock can be
189
locked multiple times by the same process without blocking, and
190
will only be unlocked after a corresponding number of unlock()
194
void QLock::lock(Type t)
196
#ifndef QT_NO_QWS_MULTIPROCESS
198
#ifdef Q_NO_SEMAPHORE
203
rv = flock(data->id, op);
204
if (rv == -1 && errno != EINTR)
205
qDebug("Semop lock failure %s",strerror(errno));
210
sops.sem_flg = SEM_UNDO;
213
sops.sem_op = -MAX_LOCKS;
222
rv = semop(data->id,&sops,1);
223
if (rv == -1 && errno != EINTR)
224
qDebug("Semop lock failure %s",strerror(errno));
225
} while (rv == -1 && errno == EINTR);
233
\fn void QLock::unlock()
235
Unlocks the semaphore. If other processes were blocking waiting to
236
lock() the semaphore, one of them will wake up and succeed in
242
#ifndef QT_NO_QWS_MULTIPROCESS
246
#ifdef Q_NO_SEMAPHORE
248
rv = flock(data->id, LOCK_UN);
249
if (rv == -1 && errno != EINTR)
250
qDebug("Semop lock failure %s",strerror(errno));
256
sops.sem_flg = SEM_UNDO;
258
sops.sem_op = MAX_LOCKS;
262
rv = semop(data->id,&sops,1);
263
if (rv == -1 && errno != EINTR)
264
qDebug("Semop unlock failure %s",strerror(errno));
265
} while (rv == -1 && errno == EINTR);
269
qDebug("Unlock without corresponding lock");
275
\fn bool QLock::locked() const
277
Returns true if the lock is currently held by the current process;
278
otherwise returns false.
281
bool QLock::locked() const
283
#ifndef QT_NO_QWS_MULTIPROCESS
284
return (data->count > 0);