158 return QString(); |
158 return QString(); |
159 |
159 |
160 QString result = prefix; |
160 QString result = prefix; |
161 |
161 |
162 QString part1 = key; |
162 QString part1 = key; |
163 part1.replace(QRegExp(QLatin1String("[^A-Za-z]")), QString()); |
163 part1.remove(QRegExp(QLatin1String("[^A-Za-z]"))); |
164 result.append(part1); |
164 result.append(part1); |
165 |
165 |
166 QByteArray hex = QCryptographicHash::hash(key.toUtf8(), QCryptographicHash::Sha1).toHex(); |
166 QByteArray hex = QCryptographicHash::hash(key.toUtf8(), QCryptographicHash::Sha1).toHex(); |
167 result.append(QLatin1String(hex)); |
167 result.append(QLatin1String(hex)); |
168 return QDir::tempPath() + QLatin1Char('/') + result; |
168 return QDir::tempPath() + QLatin1Char('/') + result; |
234 |
234 |
235 int built = createUnixKeyFile(d->keyFileName); |
235 int built = createUnixKeyFile(d->keyFileName); |
236 if (built == -1) { |
236 if (built == -1) { |
237 d->setError(QObject::tr("QSystemReadWriteLock::QSystemReadWriteLock: " |
237 d->setError(QObject::tr("QSystemReadWriteLock::QSystemReadWriteLock: " |
238 "unable to make key file for key: %1(%2)") |
238 "unable to make key file for key: %1(%2)") |
239 .arg(key).arg(strerror(errno))); |
239 .arg(key).arg(QString::fromLatin1(strerror(errno)))); |
240 return; |
240 return; |
241 } |
241 } |
242 |
242 |
243 // Get the unix key for the created file |
243 // Get the unix key for the created file |
244 d->id = ftok(QFile::encodeName(d->keyFileName).constData(), 'Q'); |
244 d->id = ftok(QFile::encodeName(d->keyFileName).constData(), 'Q'); |
245 if (d->id == -1) { |
245 if (d->id == -1) { |
246 d->setError(QObject::tr("QSystemReadWriteLock::QSystemReadWriteLock: " |
246 d->setError(QObject::tr("QSystemReadWriteLock::QSystemReadWriteLock: " |
247 "ftok failed for key %1(%2)") |
247 "ftok failed for key %1(%2)") |
248 .arg(key).arg(strerror(errno))); |
248 .arg(key).arg(QString::fromLatin1(strerror(errno)))); |
249 return; |
249 return; |
250 } |
250 } |
251 |
251 |
252 d->semId = ::semget(d->id, 4, IPC_CREAT | IPC_EXCL | 0666); |
252 d->semId = ::semget(d->id, 4, IPC_CREAT | IPC_EXCL | 0666); |
253 bool created = false; |
253 bool created = false; |
256 d->semId = ::semget(d->id, 4, |
256 d->semId = ::semget(d->id, 4, |
257 (mode == QSystemReadWriteLock::Create)?IPC_CREAT|0666:0); |
257 (mode == QSystemReadWriteLock::Create)?IPC_CREAT|0666:0); |
258 if (d->semId == -1) { |
258 if (d->semId == -1) { |
259 d->setError(QObject::tr("QSystemReadWriteLock::QSystemReadWriteLock: " |
259 d->setError(QObject::tr("QSystemReadWriteLock::QSystemReadWriteLock: " |
260 "Unable to access semaphore set for key %1(%2)") |
260 "Unable to access semaphore set for key %1(%2)") |
261 .arg(key).arg(::strerror(errno))); |
261 .arg(key).arg(QString::fromLatin1(strerror(errno)))); |
262 return; |
262 return; |
263 } |
263 } |
264 } else { |
264 } else { |
265 d->setError(QObject::tr("QSystemReadWriteLock:QSystemReadWriteLock: " |
265 d->setError(QObject::tr("QSystemReadWriteLock:QSystemReadWriteLock: " |
266 "Unable to access semaphore set for key %1(%2)") |
266 "Unable to access semaphore set for key %1(%2)") |
267 .arg(key).arg(::strerror(errno))); |
267 .arg(key).arg(QString::fromLatin1(strerror(errno)))); |
268 return; |
268 return; |
269 } |
269 } |
270 } else { |
270 } else { |
271 created = true; |
271 created = true; |
272 } |
272 } |
294 -1 == ::semctl(d->semId, QSystemReadWriteLockPrivate::NumInstances, |
294 -1 == ::semctl(d->semId, QSystemReadWriteLockPrivate::NumInstances, |
295 SETVAL, counterInitVal)) |
295 SETVAL, counterInitVal)) |
296 { |
296 { |
297 d->setError(QObject::tr("QSystemReadWriteLock::QSystemReadWriteLock: " |
297 d->setError(QObject::tr("QSystemReadWriteLock::QSystemReadWriteLock: " |
298 "Unable to reset semaphore set for key %1(%2)") |
298 "Unable to reset semaphore set for key %1(%2)") |
299 .arg(key).arg(::strerror(errno))); |
299 .arg(key).arg(QString::fromLatin1(strerror(errno)))); |
300 QFile::remove(d->keyFileName); |
300 QFile::remove(d->keyFileName); |
301 ::semctl(d->semId, 0, IPC_RMID); |
301 ::semctl(d->semId, 0, IPC_RMID); |
302 d->semId = -1; |
302 d->semId = -1; |
303 return; |
303 return; |
304 } |
304 } |
310 op.sem_flg = SEM_UNDO; |
310 op.sem_flg = SEM_UNDO; |
311 int semoprv = ::semop(d->semId, &op, 1); |
311 int semoprv = ::semop(d->semId, &op, 1); |
312 if (semoprv == -1) { |
312 if (semoprv == -1) { |
313 d->setError(QObject::tr("QSystemReadWriteLock::QSystemReadWriteLock: " |
313 d->setError(QObject::tr("QSystemReadWriteLock::QSystemReadWriteLock: " |
314 "Unable to increment NumInstances semaphore " |
314 "Unable to increment NumInstances semaphore " |
315 "for key%1(%2)").arg(key).arg(::strerror(errno))); |
315 "for key%1(%2)").arg(key).arg(QString::fromLatin1(strerror(errno)))); |
316 d->semId = -1; |
316 d->semId = -1; |
317 return; |
317 return; |
318 } |
318 } |
319 } |
319 } |
320 |
320 |
338 |
338 |
339 //if successful, then delete the semaphore set |
339 //if successful, then delete the semaphore set |
340 int semoprv = ::semop(d->semId, ops, 2); |
340 int semoprv = ::semop(d->semId, ops, 2); |
341 if (semoprv == 0) { |
341 if (semoprv == 0) { |
342 if(::semctl(d->semId, 0, IPC_RMID) == -1) { |
342 if(::semctl(d->semId, 0, IPC_RMID) == -1) { |
343 qWarning(QObject::tr("QSystemReadWriteLock::~QSystemReadWriteLock: " |
343 qWarning("QSystemReadWriteLock::~QSystemReadWriteLock: " |
344 "Unable to remove semaphore %1(%2)") |
344 "Unable to remove semaphore %s(%s)", |
345 .arg(d->key).arg(::strerror(errno)).toLatin1()); |
345 d->key.toLocal8Bit().constData(), strerror(errno)); |
346 } |
346 } |
347 QFile::remove(d->keyFileName); |
347 QFile::remove(d->keyFileName); |
348 } else { |
348 } else { |
349 if (errno == EAGAIN) { |
349 if (errno == EAGAIN) { |
350 //wasn't 0 instances so just decrement the NumInstances semaphore |
350 //wasn't 0 instances so just decrement the NumInstances semaphore |
351 if (::semop(d->semId, ops, 1) == -1) { |
351 if (::semop(d->semId, ops, 1) == -1) { |
352 qWarning(QObject::tr("QSystemReadWriteLock::~QSystemReadWriteLock: unable " |
352 qWarning("QSystemReadWriteLock::~QSystemReadWriteLock: " |
353 "to decrement NumInstances semaphore for key %1(%2)") |
353 "Unable to decrement NumInstances semaphore for key %s(%s)", |
354 .arg(d->key).arg(::strerror(errno)).toLatin1()); |
354 d->key.toLocal8Bit().constData(), strerror(errno)); |
355 } |
355 } |
356 } else { |
356 } else { |
357 qWarning(QObject::tr("QSystemReadWriteLock::~QSystemReadWriteLock: unable " |
357 qWarning("QSystemReadWriteLock::~QSystemReadWriteLock: " |
358 "to decrement and check NumInstances semaphore for key %1(%2)") |
358 "Unable to decrement and check NumInstances semaphore for key %s(%s)", |
359 .arg(d->key).arg(::strerror(errno)).toLatin1()); |
359 d->key.toLocal8Bit().constData(), strerror(errno)); |
360 ::semop(d->semId, ops, 1);//try decrement anyway |
360 ::semop(d->semId, ops, 1);//try decrement anyway |
361 } |
361 } |
362 } |
362 } |
363 |
363 |
364 } |
364 } |
381 has locked for writing. |
381 has locked for writing. |
382 */ |
382 */ |
383 bool QSystemReadWriteLock::lockForRead() |
383 bool QSystemReadWriteLock::lockForRead() |
384 { |
384 { |
385 if (d->semId == -1) { |
385 if (d->semId == -1) { |
386 d->errorString = QObject::tr("QSystemReadWriteLock::lockForRead: unable to lock for read for key %1(%2)") |
386 d->errorString = QObject::tr("QSystemReadWriteLock::lockForRead: " |
387 .arg(d->key).arg("Lock had not been correctly initialized"); |
387 "Unable to lock for read for key %1" |
|
388 "(Lock had not been correctly initialized)").arg(d->key); |
388 d->error = UnknownError; |
389 d->error = UnknownError; |
389 return false; |
390 return false; |
390 } |
391 } |
391 |
392 |
392 struct sembuf ops[2]; |
393 struct sembuf ops[2]; |
398 ops[1].sem_num = QSystemReadWriteLockPrivate::TotalWriters; |
399 ops[1].sem_num = QSystemReadWriteLockPrivate::TotalWriters; |
399 ops[1].sem_op = 0; |
400 ops[1].sem_op = 0; |
400 ops[1].sem_flg = 0; |
401 ops[1].sem_flg = 0; |
401 |
402 |
402 if (-1 == ::semop(d->semId, ops, 2)) { |
403 if (-1 == ::semop(d->semId, ops, 2)) { |
403 d->setError(QObject::tr("QSystemReadWriteLock::lockForRead: unable to lock for read for key %1(%2)") |
404 d->setError(QObject::tr("QSystemReadWriteLock::lockForRead: " |
404 .arg(d->key).arg(::strerror(errno))); |
405 "Unable to lock for read for key %1(%2)") |
|
406 .arg(d->key).arg(QString::fromLatin1(strerror(errno)))); |
405 return false; |
407 return false; |
406 } else { |
408 } else { |
407 d->errorString = ""; |
409 d->errorString.clear(); |
408 d->error = NoError; |
410 d->error = NoError; |
409 return true; |
411 return true; |
410 } |
412 } |
411 } |
413 } |
412 |
414 |
416 */ |
418 */ |
417 bool QSystemReadWriteLock::lockForWrite() |
419 bool QSystemReadWriteLock::lockForWrite() |
418 { |
420 { |
419 if (d->semId == -1) { |
421 if (d->semId == -1) { |
420 d->errorString = QObject::tr("QSystemReadWriteLock::lockForWrite: " |
422 d->errorString = QObject::tr("QSystemReadWriteLock::lockForWrite: " |
421 "unable to lock for write for key %1(%2)") |
423 "Unable to lock for write for key %1" |
422 .arg(d->key).arg("Lock had not been correctly initialized"); |
424 "(Lock had not been correctly initialized)").arg(d->key); |
423 d->error = UnknownError; |
425 d->error = UnknownError; |
424 return false; |
426 return false; |
425 } |
427 } |
426 |
428 |
427 struct sembuf op; |
429 struct sembuf op; |
430 op.sem_flg = SEM_UNDO; |
432 op.sem_flg = SEM_UNDO; |
431 |
433 |
432 int semoprv = ::semop(d->semId, &op, 1); |
434 int semoprv = ::semop(d->semId, &op, 1); |
433 if (semoprv == -1) { |
435 if (semoprv == -1) { |
434 d->setError(QObject::tr("QSystemReadWriteLock::lockForWrite: " |
436 d->setError(QObject::tr("QSystemReadWriteLock::lockForWrite: " |
435 "Could not increment TotalWriters semaphore for key %1(%2)") |
437 "Could not increment TotalWriters semaphore for key %1(%2)") |
436 .arg(d->key).arg(::strerror(errno))); |
438 .arg(d->key).arg(QString::fromLatin1(strerror(errno)))); |
437 return false; |
439 return false; |
438 } |
440 } |
439 |
441 |
440 op.sem_num = QSystemReadWriteLockPrivate::ActiveReaders; |
442 op.sem_num = QSystemReadWriteLockPrivate::ActiveReaders; |
441 op.sem_op = 0; |
443 op.sem_op = 0; |
442 op.sem_flg = 0; |
444 op.sem_flg = 0; |
443 semoprv = ::semop(d->semId, &op, 1); |
445 semoprv = ::semop(d->semId, &op, 1); |
444 if (semoprv == -1) { |
446 if (semoprv == -1) { |
445 d->setError(QObject::tr("QSystemReadWriteLock::lockForWrite: " |
447 d->setError(QObject::tr("QSystemReadWriteLock::lockForWrite: " |
446 "Could not detect if all readers were finished for key %1(%2)") |
448 "Could not detect if all readers were finished for key %1(%2)") |
447 .arg(d->key).arg(::strerror(errno))); |
449 .arg(d->key).arg(QString::fromLatin1(strerror(errno)))); |
448 |
450 |
449 // Decrement our write lock |
451 // Decrement our write lock |
450 op.sem_num = QSystemReadWriteLockPrivate::TotalWriters; |
452 op.sem_num = QSystemReadWriteLockPrivate::TotalWriters; |
451 op.sem_op = -1; |
453 op.sem_op = -1; |
452 op.sem_flg = SEM_UNDO; |
454 op.sem_flg = SEM_UNDO; |
458 op.sem_flg =SEM_UNDO; |
460 op.sem_flg =SEM_UNDO; |
459 semoprv = ::semop(d->semId, &op, 1); |
461 semoprv = ::semop(d->semId, &op, 1); |
460 |
462 |
461 if (semoprv == -1) { |
463 if (semoprv == -1) { |
462 d->setError(QObject::tr("QSystemReadWriteLock::lockForWrite: " |
464 d->setError(QObject::tr("QSystemReadWriteLock::lockForWrite: " |
463 "Could not decrement ActiveWriterSem semaphore for key %1(%2)") |
465 "Could not decrement ActiveWriterSem semaphore for key %1(%2)") |
464 .arg(d->key).arg(::strerror(errno))); |
466 .arg(d->key).arg(QString::fromLatin1(strerror(errno)))); |
465 |
467 |
466 op.sem_num = QSystemReadWriteLockPrivate::TotalWriters; |
468 op.sem_num = QSystemReadWriteLockPrivate::TotalWriters; |
467 op.sem_op = -1; |
469 op.sem_op = -1; |
468 op.sem_flg = 0; |
470 op.sem_flg = 0; |
469 ::semop(d->semId, &op, 1); |
471 ::semop(d->semId, &op, 1); |
470 return false; |
472 return false; |
471 } |
473 } |
472 d->errorString =""; |
474 d->errorString.clear(); |
473 d->error = NoError; |
475 d->error = NoError; |
474 return true; |
476 return true; |
475 } |
477 } |
476 } |
478 } |
477 |
479 |
479 Release the lock. |
481 Release the lock. |
480 */ |
482 */ |
481 void QSystemReadWriteLock::unlock() |
483 void QSystemReadWriteLock::unlock() |
482 { |
484 { |
483 if (d->semId == -1) { |
485 if (d->semId == -1) { |
484 d->errorString = QObject::tr("QSystemReadWriteLock::unlock: unable to unlock for key %1(%2)") |
486 d->errorString = QObject::tr("QSystemReadWriteLock::unlock: " |
485 .arg(d->key).arg("Lock had not been correctly initialized"); |
487 "Unable to unlock for key %1" |
|
488 "(Lock had not been correctly initialized)").arg(d->key); |
486 d->error = UnknownError; |
489 d->error = UnknownError; |
487 return; |
490 return; |
488 } |
491 } |
489 |
492 |
490 struct sembuf op; |
493 struct sembuf op; |
507 ops[2].sem_op = -1; |
510 ops[2].sem_op = -1; |
508 ops[2].sem_flg = SEM_UNDO; |
511 ops[2].sem_flg = SEM_UNDO; |
509 |
512 |
510 if (::semop(d->semId, ops, 3) == -1) { |
513 if (::semop(d->semId, ops, 3) == -1) { |
511 if (errno != EAGAIN) { |
514 if (errno != EAGAIN) { |
512 d->setError(QObject::tr("QSystemSemaphoreWriteLock::unlock: unable to check and " |
515 d->setError(QObject::tr("QSystemSemaphoreWriteLock::unlock: " |
513 "update writer semaphores for key %1(%2)") |
516 "Unable to check and update writer semaphores for key %1(%2)") |
514 .arg(d->key).arg(::strerror(errno))); |
517 .arg(d->key).arg(QString::fromLatin1(strerror(errno)))); |
515 return; |
518 return; |
516 } //Note: EAGAIN indicates that ActiveWriterSem is has a non zero value |
519 } //Note: EAGAIN indicates that ActiveWriterSem is has a non zero value |
517 //indicating there is no current writer, so nothing needs to be done |
520 //indicating there is no current writer, so nothing needs to be done |
518 } |
521 } |
519 } else { |
522 } else { |
520 //error in decrementing readers |
523 //error in decrementing readers |
521 d->setError(QObject::tr("QSystemReadWriteLock::unlock: unable to decrement " |
524 d->setError(QObject::tr("QSystemReadWriteLock::unlock: " |
522 "ActiveReaders semaphore for key %1(%2)") |
525 "Unable to decrement ActiveReaders semaphore for key %1(%2)") |
523 .arg(d->key).arg(::strerror(errno))); |
526 .arg(d->key).arg(QString::fromLatin1(strerror(errno)))); |
524 return; |
527 return; |
525 } |
528 } |
526 d->errorString=""; |
529 d->errorString.clear(); |
527 d->error = NoError; |
530 d->error = NoError; |
528 } |
531 } |
529 |
532 |
530 /* |
533 /* |
531 Returns the error code of the last encountered error |
534 Returns the error code of the last encountered error |