qtmobility/src/publishsubscribe/qsystemreadwritelock_unix.cpp
changeset 14 6fbed849b4f4
parent 11 06b8e2af4411
equal deleted inserted replaced
11:06b8e2af4411 14:6fbed849b4f4
   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