1
/****************************************************************************
3
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4
** All rights reserved.
5
** Contact: Nokia Corporation (qt-info@nokia.com)
7
** This file is part of the QtGui module of the Qt Toolkit.
9
** $QT_BEGIN_LICENSE:LGPL$
10
** No Commercial Usage
11
** This file contains pre-release code and may not be distributed.
12
** You may use this file in accordance with the terms and conditions
13
** contained in the Technology Preview License Agreement accompanying
16
** GNU Lesser General Public License Usage
17
** Alternatively, this file may be used under the terms of the GNU Lesser
18
** General Public License version 2.1 as published by the Free Software
19
** Foundation and appearing in the file LICENSE.LGPL included in the
20
** packaging of this file. Please review the following information to
21
** ensure the GNU Lesser General Public License version 2.1 requirements
22
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24
** In addition, as a special exception, Nokia gives you certain additional
25
** rights. These rights are described in the Nokia Qt LGPL Exception
26
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28
** If you have questions regarding the use of this file, please contact
29
** Nokia at qt-info@nokia.com.
40
****************************************************************************/
45
#ifdef QT_NO_QWS_MULTIPROCESS
49
/* no multiprocess - use a dummy */
51
QLock::QLock(const QString & /*filename*/, char /*id*/, bool /*create*/)
60
bool QLock::isValid() const
65
void QLock::lock(Type t)
67
data = (QLockData *)-1;
76
bool QLock::locked() const
83
#else // QT_NO_QWS_MULTIPROCESS
85
#include "qwssignalhandler_p.h"
88
#include <sys/types.h>
89
#if defined(Q_OS_DARWIN)
90
# define Q_NO_SEMAPHORE
91
# include <sys/stat.h>
92
# include <sys/file.h>
95
# if (defined(__GNU_LIBRARY__) && !defined(_SEM_SEMUN_UNDEFINED) && !defined(QT_LINUXBASE)) \
96
|| defined(Q_OS_FREEBSD) || defined(Q_OS_OPENBSD) || defined(Q_OS_NETBSD) \
98
/* union semun is defined by including <sys/sem.h> */
100
/* according to X/OPEN we have to define it ourselves */
102
int val; /* value for SETVAL */
103
struct semid_ds *buf; /* buffer for IPC_STAT, IPC_SET */
104
unsigned short *array; /* array for GETALL, SETALL */
107
#endif // Q_OS_DARWIN
114
#include <private/qcore_unix_p.h> // overrides QT_OPEN
119
#define MAX_LOCKS 200 // maximum simultaneous read locks
124
#ifdef Q_NO_SEMAPHORE
126
#endif // Q_NO_SEMAPHORE
134
\brief The QLock class is a wrapper for a System V shared semaphore.
140
It is used by \l{Qt for Embedded Linux} for synchronizing access to the graphics
141
card and shared memory region between processes.
152
\fn QLock::QLock(const QString &filename, char id, bool create)
154
Creates a lock. \a filename is the file path of the Unix-domain
155
socket the \l{Qt for Embedded Linux} client is using. \a id is the name of the
156
particular lock to be created on that socket. If \a create is true
157
the lock is to be created (as the Qt for Embedded Linux server does); if \a
158
create is false the lock should exist already (as the Qt for Embedded Linux
162
QLock::QLock(const QString &filename, char id, bool create)
164
data = new QLockData;
166
#ifdef Q_NO_SEMAPHORE
167
data->file = QString(filename+id).toLocal8Bit().constData();
168
for(int x = 0; x < 2; x++) {
169
data->id = QT_OPEN(data->file, O_RDWR | (x ? O_CREAT : 0), S_IRWXU);
170
if(data->id != -1 || !create) {
176
key_t semkey = ftok(filename.toLocal8Bit().constData(), id);
177
data->id = semget(semkey,0,0);
178
data->owned = create;
180
semun arg; arg.val = 0;
182
semctl(data->id,0,IPC_RMID,arg);
183
data->id = semget(semkey,1,IPC_CREAT|0600);
185
semctl(data->id,0,SETVAL,arg);
187
QWSSignalHandler::instance()->addSemaphore(data->id);
190
if (data->id == -1) {
192
qWarning("Cannot %s semaphore %s '%c'", (create ? "create" : "get"),
193
qPrintable(filename), id);
194
qDebug() << "Error" << eno << strerror(eno);
208
#ifdef Q_NO_SEMAPHORE
216
QWSSignalHandler::instance()->removeSemaphore(data->id);
222
\fn bool QLock::isValid() const
224
Returns true if the lock constructor was successful; returns false if
225
the lock could not be created or was not available to connect to.
228
bool QLock::isValid() const
230
return (data->id != -1);
234
Locks the semaphore with a lock of type \a t. Locks can either be
235
\c Read or \c Write. If a lock is \c Read, attempts by other
236
processes to obtain \c Read locks will succeed, and \c Write
237
attempts will block until the lock is unlocked. If locked as \c
238
Write, all attempts to lock by other processes will block until
239
the lock is unlocked. Locks are stacked: i.e. a given QLock can be
240
locked multiple times by the same process without blocking, and
241
will only be unlocked after a corresponding number of unlock()
245
void QLock::lock(Type t)
248
#ifdef Q_NO_SEMAPHORE
253
rv = flock(data->id, op);
254
if (rv == -1 && errno != EINTR)
255
qDebug("Semop lock failure %s",strerror(errno));
260
sops.sem_flg = SEM_UNDO;
263
sops.sem_op = -MAX_LOCKS;
272
rv = semop(data->id,&sops,1);
273
if (rv == -1 && errno != EINTR)
274
qDebug("Semop lock failure %s",strerror(errno));
275
} while (rv == -1 && errno == EINTR);
282
\fn void QLock::unlock()
284
Unlocks the semaphore. If other processes were blocking waiting to
285
lock() the semaphore, one of them will wake up and succeed in
294
#ifdef Q_NO_SEMAPHORE
296
rv = flock(data->id, LOCK_UN);
297
if (rv == -1 && errno != EINTR)
298
qDebug("Semop lock failure %s",strerror(errno));
304
sops.sem_flg = SEM_UNDO;
306
sops.sem_op = MAX_LOCKS;
310
rv = semop(data->id,&sops,1);
311
if (rv == -1 && errno != EINTR)
312
qDebug("Semop unlock failure %s",strerror(errno));
313
} while (rv == -1 && errno == EINTR);
317
qDebug("Unlock without corresponding lock");
322
\fn bool QLock::locked() const
324
Returns true if the lock is currently held by the current process;
325
otherwise returns false.
328
bool QLock::locked() const
330
return (data->count > 0);
335
#endif // QT_NO_QWS_MULTIPROCESS