FileLock::FileLock( const char *path , bool deleteFile, bool useLiteralPath) : FileLockBase( ) { Reset( ); ASSERT(path != NULL); #ifndef WIN32 if (deleteFile) { char *hPath = NULL; m_delete = 1; if (useLiteralPath) { SetPath(path); } else { hPath = CreateHashName(path); SetPath(hPath); delete []hPath; } SetPath(path, true); m_init_succeeded = initLockFile(useLiteralPath); } else { SetPath(path); } updateLockTimestamp(); #else SetPath(path); updateLockTimestamp(); #endif }
int main(int argc, char **argv) { exitCode = 0; initGtk(&argc, &argv); migrateConfigToXdgDir(); migrateThemesToXdgDir(); initDataDefault(); if (parseCommandline(&argc, &argv)) { if(initLockFile()) { printMessage(MSG_INFO, "Startup %s %s (-h to print usage)\n", OBS_NAME, OBS_VERSION); if (initConfigs()) { initWidgets(); gtk_widget_show_all(winWidget); gtk_main(); } else exitCode = 1; deleteLockFile(); } else exitCode = 1; } else exitCode = 1; freeData(); exit(exitCode); }
bool FileLock::obtain( LOCK_TYPE t ) { int counter = 0; #if !defined(WIN32) start: #endif // lock_file uses lseeks in order to lock the first 4 bytes of the file on NT // It DOES properly reset the lseek version of the file position, but that is // not the same (in some very inconsistent and weird ways) as the fseek one, // so if the user has given us a FILE *, we need to make sure we don't ruin // their current position. The lesson here is don't use fseeks and lseeks // interchangeably... int status = -1; int saved_errno = -1; if ( m_use_kernel_mutex == -1 ) { m_use_kernel_mutex = param_boolean_int("FILE_LOCK_VIA_MUTEX", TRUE); } // If we have the path, we can try to lock via a mutex. if ( m_path && m_use_kernel_mutex ) { status = lockViaMutex(t); } // We cannot lock via a mutex, or we tried and failed. // Try via filesystem lock. if ( status < 0) { long lPosBeforeLock = 0; if (m_fp) // if the user has a FILE * as well as an fd { // save their FILE*-based current position lPosBeforeLock = ftell(m_fp); } // We're seeing sporadic test suite failures where a daemon // takes more than 10 seconds to write to the user log. // This will help narrow down where the delay is coming from. time_t before = time(NULL); status = lock_file( m_fd, t, m_blocking ); saved_errno = errno; time_t after = time(NULL); if ( (after - before) > 5 ) { dprintf( D_FULLDEBUG, "FileLock::obtain(%d): lock_file() took %ld seconds\n", t, (after-before) ); } if (m_fp) { // restore their FILE*-position fseek(m_fp, lPosBeforeLock, SEEK_SET); } #ifndef WIN32 // if we deal with our own fd and are not unlocking if (m_delete == 1 && t != UN_LOCK){ struct stat si; fstat(m_fd, &si); // no more hard links ... it was deleted while we were waiting // in that case we need to reopen and restart if ( si.st_nlink < 1 ){ release(); close(m_fd); bool initResult; if (m_orig_path != NULL && strcmp(m_path, m_orig_path) != 0) initResult = initLockFile(false); else initResult = initLockFile(true); if (!initResult) { dprintf(D_FULLDEBUG, "Lock file (%s) cannot be reopened \n", m_path); if (m_orig_path) { dprintf(D_FULLDEBUG, "Opening and locking the actual log file (%s) since lock file cannot be accessed! \n", m_orig_path); m_fd = safe_open_wrapper_follow(m_orig_path, O_CREAT | O_RDWR , 0644); } } if (m_fd < 0) { dprintf(D_FULLDEBUG, "Opening the log file %s to lock failed. \n", m_path); } ++counter; // let's retry at most 5 times if (counter < 6) { goto start; } else status = -1; } } #endif } if( status == 0 ) { m_state = t; } if ( status != 0 ) { dprintf( D_ALWAYS, "FileLock::obtain(%d) failed - errno %d (%s)\n", t, saved_errno, strerror(saved_errno) ); } else { UtcTime now( true ); dprintf( D_FULLDEBUG, "FileLock::obtain(%d) - @%.6f lock on %s now %s\n", t, now.combined(), m_path, getStateString(t) ); } return status == 0; }