Qt 4.8
Public Types | Public Functions | Properties | List of all members
QLock Class Reference

The QLock class is a wrapper for a system shared semaphore. More...

#include <qlock_p.h>

Public Types

enum  Type { Read, Write }
 

Public Functions

bool isValid () const
 Returns true if the lock constructor was successful; returns false if the lock could not be created or was not available to connect to. More...
 
void lock (Type type)
 Locks the semaphore with a lock of type t. More...
 
bool locked () const
 Returns true if the lock is currently held by the current process; otherwise returns false. More...
 
 QLock (const QString &filename, char id, bool create=false)
 Creates a lock. More...
 
void unlock ()
 Unlocks the semaphore. More...
 
 ~QLock ()
 Destroys a lock. More...
 

Properties

QLockDatadata
 
Type type
 

Detailed Description

The QLock class is a wrapper for a system shared semaphore.

Warning
This function is not part of the public interface.

It is used by Qt for Embedded Linux for synchronizing access to the graphics card and shared memory region between processes.

Definition at line 62 of file qlock_p.h.

Enumerations

◆ Type

  • Read
  • Write
Enumerator
Read 
Write 

Definition at line 68 of file qlock_p.h.

68 { Read, Write };

Constructors and Destructors

◆ QLock()

QLock::QLock ( const QString filename,
char  id,
bool  create = false 
)

Creates a lock.

filename is the file path of the Unix-domain socket the Qt for Embedded Linux client is using. id is the name of the particular lock to be created on that socket. If create is true the lock is to be created (as the Qt for Embedded Linux server does); if create is false the lock should exist already (as the Qt for Embedded Linux client expects).

Definition at line 158 of file qlock.cpp.

159 {
160  data = new QLockData;
161  data->count = 0;
162 #if defined(QT_NO_SEMAPHORE)
163  data->file = filename.toLocal8Bit() + id;
164  for (int x = 0; x < 2; ++x) {
165  data->id = QT_OPEN(data->file.constData(), O_RDWR | (x ? O_CREAT : 0), S_IRWXU);
166  if (data->id != -1 || !create) {
167  data->owned = x;
168  break;
169  }
170  }
171 #elif !defined(QT_POSIX_IPC)
172  key_t semkey = ftok(filename.toLocal8Bit().constData(), id);
173  data->id = semget(semkey, 0, 0);
174  data->owned = create;
175  if (create) {
176  qt_semun arg;
177  arg.val = 0;
178  if (data->id != -1)
179  semctl(data->id, 0, IPC_RMID, arg);
180  data->id = semget(semkey, 1, IPC_CREAT | 0600);
181  arg.val = MAX_LOCKS;
182  semctl(data->id, 0, SETVAL, arg);
183  }
184 #else
185  data->file = filename.toLocal8Bit() + id;
186  data->owned = create;
187 
188  char ids[3] = { 'c', 'r', 'w' };
189  sem_t **sems[3] = { &data->id, &data->rsem, &data->wsem };
190  unsigned short initialValues[3] = { MAX_LOCKS, 1, 1 };
191  for (int i = 0; i < 3; ++i) {
192  QByteArray file = data->file + ids[i];
193  do {
194  *sems[i] = sem_open(file.constData(), 0, 0666, 0);
195  } while (*sems[i] == SEM_FAILED && errno == EINTR);
196  if (create) {
197  if (*sems[i] != SEM_FAILED) {
198  sem_close(*sems[i]);
199  sem_unlink(file.constData());
200  }
201  do {
202  *sems[i] = sem_open(file.constData(), O_CREAT, 0666, initialValues[i]);
203  } while (*sems[i] == SEM_FAILED && errno == EINTR);
204  }
205  }
206 #endif
207  if (!isValid()) {
208  qWarning("QLock::QLock: Cannot %s semaphore %s '%c' (%d, %s)",
209  (create ? "create" : "get"), qPrintable(filename), id,
210  errno, strerror(errno));
211  }
212 
213 #ifndef QT_NO_QWS_SIGNALHANDLER
215 #endif
216 }
#define MAX_LOCKS
Definition: qlock.cpp:108
The QByteArray class provides an array of bytes.
Definition: qbytearray.h:135
static Expression::Ptr create(Expression *const expr, const YYLTYPE &sourceLocator, const ParserContext *const parseInfo)
QLockData * data
Definition: qlock_p.h:77
bool owned
Definition: qlock.cpp:124
int id
Definition: qlock.cpp:117
#define O_CREAT
static QWSSignalHandler * instance()
int count
Definition: qlock.cpp:123
Q_CORE_EXPORT void qWarning(const char *,...)
QByteArray toLocal8Bit() const Q_REQUIRED_RESULT
Returns the local 8-bit representation of the string as a QByteArray.
Definition: qstring.cpp:4049
const char * constData() const
Returns a pointer to the data stored in the byte array.
Definition: qbytearray.h:433
#define QT_OPEN
Definition: qcore_unix_p.h:186
bool isValid() const
Returns true if the lock constructor was successful; returns false if the lock could not be created o...
Definition: qlock.cpp:265
#define qPrintable(string)
Definition: qglobal.h:1750
#define O_RDWR
QByteArray file
Definition: qlock.cpp:114
void addLock(QLock *lock)
int errno

◆ ~QLock()

QLock::~QLock ( )

Destroys a lock.

Definition at line 221 of file qlock.cpp.

Referenced by QWSSignalHandler::clear().

222 {
223 #ifndef QT_NO_QWS_SIGNALHANDLER
225 #endif
226 
227  while (locked())
228  unlock();
229 
230 #if defined(QT_NO_SEMAPHORE)
231  if (isValid())
232  QT_CLOSE(data->id);
233 #elif defined(QT_POSIX_IPC)
234  if (data->id != SEM_FAILED)
235  sem_close(data->id);
236  if (data->rsem != SEM_FAILED)
237  sem_close(data->rsem);
238  if (data->wsem != SEM_FAILED)
239  sem_close(data->wsem);
240 #endif
241 
242  if (data->owned) {
243 #if defined(QT_NO_SEMAPHORE)
244  unlink(data->file.constData());
245 #elif !defined(QT_POSIX_IPC)
246  qt_semun semval;
247  semval.val = 0;
248  semctl(data->id, 0, IPC_RMID, semval);
249 #else
250  char ids[3] = { 'c', 'r', 'w' };
251  for (int i = 0; i < 3; ++i) {
252  QByteArray file = data->file + ids[i];
253  sem_unlink(file.constData());
254  }
255 #endif
256  }
257  delete data;
258  data = 0;
259 }
The QByteArray class provides an array of bytes.
Definition: qbytearray.h:135
QLockData * data
Definition: qlock_p.h:77
bool owned
Definition: qlock.cpp:124
int id
Definition: qlock.cpp:117
void unlock()
Unlocks the semaphore.
Definition: qlock.cpp:345
static QWSSignalHandler * instance()
bool locked() const
Returns true if the lock is currently held by the current process; otherwise returns false...
Definition: qlock.cpp:391
const char * constData() const
Returns a pointer to the data stored in the byte array.
Definition: qbytearray.h:433
bool isValid() const
Returns true if the lock constructor was successful; returns false if the lock could not be created o...
Definition: qlock.cpp:265
void removeLock(QLock *lock)
QByteArray file
Definition: qlock.cpp:114
#define QT_CLOSE
Definition: qcore_unix_p.h:304

Functions

◆ isValid()

bool QLock::isValid ( ) const

Returns true if the lock constructor was successful; returns false if the lock could not be created or was not available to connect to.

Definition at line 265 of file qlock.cpp.

266 {
267 #if !defined(QT_POSIX_IPC)
268  return data && data->id != -1;
269 #else
270  return data && data->id != SEM_FAILED && data->rsem != SEM_FAILED && data->wsem != SEM_FAILED;
271 #endif
272 }
QLockData * data
Definition: qlock_p.h:77
int id
Definition: qlock.cpp:117

◆ lock()

void QLock::lock ( Type  t)

Locks the semaphore with a lock of type t.

Locks can either be Read or Write. If a lock is Read, attempts by other processes to obtain Read locks will succeed, and Write attempts will block until the lock is unlocked. If locked as Write, all attempts to lock by other processes will block until the lock is unlocked. Locks are stacked: i.e. a given QLock can be locked multiple times by the same process without blocking, and will only be unlocked after a corresponding number of unlock() calls.

Definition at line 285 of file qlock.cpp.

286 {
287  if (!isValid())
288  return;
289 
290  if (!data->count) {
291  type = t;
292 
293  int rv;
294 #if defined(QT_NO_SEMAPHORE)
295  int op = type == Write ? LOCK_EX : LOCK_SH;
296 
297  EINTR_LOOP(rv, flock(data->id, op));
298 #elif !defined(QT_POSIX_IPC)
299  sembuf sops;
300  sops.sem_num = 0;
301  sops.sem_op = type == Write ? -MAX_LOCKS : -1;
302  sops.sem_flg = SEM_UNDO;
303 
304  EINTR_LOOP(rv, semop(data->id, &sops, 1));
305 #else
306  if (type == Write) {
307  EINTR_LOOP(rv, sem_wait(data->rsem));
308  if (rv != -1) {
309  EINTR_LOOP(rv, sem_wait(data->wsem));
310  if (rv == -1)
311  sem_post(data->rsem);
312  }
313  } else {
314  EINTR_LOOP(rv, sem_wait(data->wsem));
315  if (rv != -1) {
316  EINTR_LOOP(rv, sem_trywait(data->rsem));
317  if (rv != -1 || errno == EAGAIN) {
318  EINTR_LOOP(rv, sem_wait(data->id));
319  if (rv == -1) {
320  int semval;
321  sem_getvalue(data->id, &semval);
322  if (semval == MAX_LOCKS)
323  sem_post(data->rsem);
324  }
325  }
326  rv = sem_post(data->wsem);
327  }
328  }
329 #endif
330  if (rv == -1) {
331  qDebug("QLock::lock(): %s", strerror(errno));
332  return;
333  }
334  } else if (type == Read && t == Write) {
335  qDebug("QLock::lock(): Attempt to lock for write while locked for read");
336  }
337  data->count++;
338 }
#define MAX_LOCKS
Definition: qlock.cpp:108
#define EINTR_LOOP(var, cmd)
Definition: qcore_unix_p.h:96
QLockData * data
Definition: qlock_p.h:77
int id
Definition: qlock.cpp:117
Q_CORE_EXPORT void qDebug(const char *,...)
int count
Definition: qlock.cpp:123
bool isValid() const
Returns true if the lock constructor was successful; returns false if the lock could not be created o...
Definition: qlock.cpp:265
Type type
Definition: qlock_p.h:76
int errno

◆ locked()

bool QLock::locked ( ) const

Returns true if the lock is currently held by the current process; otherwise returns false.

Definition at line 391 of file qlock.cpp.

392 {
393  return isValid() && data->count > 0;
394 }
QLockData * data
Definition: qlock_p.h:77
int count
Definition: qlock.cpp:123
bool isValid() const
Returns true if the lock constructor was successful; returns false if the lock could not be created o...
Definition: qlock.cpp:265

◆ unlock()

void QLock::unlock ( )

Unlocks the semaphore.

If other processes were blocking waiting to lock() the semaphore, one of them will wake up and succeed in locking.

Definition at line 345 of file qlock.cpp.

346 {
347  if (!isValid())
348  return;
349 
350  if (data->count > 0) {
351  data->count--;
352  if (!data->count) {
353  int rv;
354 #if defined(QT_NO_SEMAPHORE)
355  EINTR_LOOP(rv, flock(data->id, LOCK_UN));
356 #elif !defined(QT_POSIX_IPC)
357  sembuf sops;
358  sops.sem_num = 0;
359  sops.sem_op = type == Write ? MAX_LOCKS : 1;
360  sops.sem_flg = SEM_UNDO;
361 
362  EINTR_LOOP(rv, semop(data->id, &sops, 1));
363 #else
364  if (type == Write) {
365  sem_post(data->wsem);
366  rv = sem_post(data->rsem);
367  } else {
368  EINTR_LOOP(rv, sem_wait(data->wsem));
369  if (rv != -1) {
370  sem_post(data->id);
371  int semval;
372  sem_getvalue(data->id, &semval);
373  if (semval == MAX_LOCKS)
374  sem_post(data->rsem);
375  rv = sem_post(data->wsem);
376  }
377  }
378 #endif
379  if (rv == -1)
380  qDebug("QLock::unlock(): %s", strerror(errno));
381  }
382  } else {
383  qDebug("QLock::unlock(): Unlock without corresponding lock");
384  }
385 }
#define MAX_LOCKS
Definition: qlock.cpp:108
#define EINTR_LOOP(var, cmd)
Definition: qcore_unix_p.h:96
QLockData * data
Definition: qlock_p.h:77
int id
Definition: qlock.cpp:117
Q_CORE_EXPORT void qDebug(const char *,...)
int count
Definition: qlock.cpp:123
bool isValid() const
Returns true if the lock constructor was successful; returns false if the lock could not be created o...
Definition: qlock.cpp:265
Type type
Definition: qlock_p.h:76
int errno

Properties

◆ data

QLockData* QLock::data
private

Definition at line 77 of file qlock_p.h.

◆ type

Type QLock::type
private

Definition at line 76 of file qlock_p.h.


The documentation for this class was generated from the following files: