//! //! Semaphore decrement (aka lock release) function. The second parameter tells it not //! to log the event (useful for avoiding infinite recursion when unlocking from the //! logging code) //! //! @param[in] pSem pointer to the semaphore to release //! @param[in] doLog set to TRUE if we need to log this acquisition. Otherwise set to FALSE. //! //! @return 0 on success or any other values on failure //! //! @pre The pSem field must not be NULL //! //! @post On success, the semaphore has successfully been released. //! int sem_verhogen(sem * pSem, boolean doLog) { int rc = 0; struct sembuf sb = { 0, 1, 0 }; // Make sure our given semaphore is valid if (pSem) { // Check if we need to log this operation now if (doLog) { LOGEXTREME("%s unlocking\n", pSem->name); } // For mutex semaphore if (pSem->usemutex) { rc = pthread_mutex_lock(&(pSem->mutex)); if (pSem->mutwaiters > 0) { rc = pthread_cond_signal(&(pSem->cond)); } pSem->mutcount++; rc = pthread_mutex_unlock(&(pSem->mutex)); return (rc); } // For Posix semaphore if (pSem->posix) { return (sem_post(pSem->posix)); } // For SYS V semaphore if (pSem->sysv > 0) { return (semop(pSem->sysv, &sb, 1)); } } return (-1); }
//! //! //! //! @param[in] fp //! //! @return a pointer to the file output string //! //! @pre \li The fp field MUST not be NULL. //! \li The file handles must have previously been opened. //! //! @post The file remains open regardless of the result. //! //! @note caller is responsible to free the returned memory //! char *fp2str(FILE * fp) { #define INCREMENT 512 int buf_max = INCREMENT; int buf_current = 0; void *new_buf = NULL; char *last_read = NULL; char *buf = NULL; if (fp == NULL) return (NULL); do { // create/enlarge the buffer if ((new_buf = EUCA_REALLOC(buf, buf_max, sizeof(char))) == NULL) { // free partial buffer EUCA_FREE(buf); return (NULL); } memset((new_buf + buf_current), 0, (INCREMENT * sizeof(char))); buf = new_buf; LOGEXTREME("enlarged buf to %d\n", buf_max); do { // read in until EOF or buffer is full last_read = fgets(buf + buf_current, buf_max - buf_current, fp); if (last_read != NULL) { buf_current = strlen(buf); } else if (!feof(fp)) { LOGERROR("failed while reading from file handle\n"); EUCA_FREE(buf); return (NULL); } LOGEXTREME("read %d characters so far (max=%d, last=%s)\n", buf_current, buf_max, last_read ? "no" : "yes"); } while (last_read && (buf_max > (buf_current + 1))); // +1 is needed for fgets() to put \0 // in case it is full buf_max += INCREMENT; } while (last_read); return (buf); #undef INCREMENT }
//! //! Semaphore increment (aka lock acquisition) function. The second parameter //! tells it not to log the event (useful for avoiding infinite recursion when //! locking from the logging code). //! //! @param[in] pSem a pointer to the semaphore to acquire //! @param[in] doLog set to TRUE if we need to log this acquisition. Otherwise set to FALSE. //! //! @return 0 on success or any other values on failure //! //! @pre The pSem field must not be NULL. //! //! @post On success, the sempahore is acquired //! int sem_prolaag(sem * pSem, boolean doLog) { int rc = 0; struct sembuf sb = { 0, -1, 0 }; // Make sure our given semaphore is valid if (pSem) { // Check if we need to log this operation now if (doLog) { LOGEXTREME("%s locking\n", pSem->name); } // For mutex semaphore if (pSem->usemutex) { rc = pthread_mutex_lock(&(pSem->mutex)); pSem->mutwaiters++; while (pSem->mutcount == 0) { pthread_cond_wait(&(pSem->cond), &(pSem->mutex)); } pSem->mutwaiters--; pSem->mutcount--; rc = pthread_mutex_unlock(&(pSem->mutex)); return (rc); } // For Posix semaphore if (pSem->posix) { return (sem_wait(pSem->posix)); } // For SYS V semaphore if (pSem->sysv > 0) { return (semop(pSem->sysv, &sb, 1)); } } return (-1); }
//! //! //! //! @param[in] msg //! //! @pre //! //! @post //! static void bs_errors(const char *msg) { // we normally do not care to print all messages from blobstore as many are errors that we can handle LOGEXTREME("blobstore: %s", msg); }