From c00931f204af4e4772872b987da2356776ff22e5 Mon Sep 17 00:00:00 2001 From: Ingo Weinhold Date: Wed, 7 May 2008 12:10:38 +0000 Subject: [PATCH] * Don't try to strdup() the name given for an unnamed semaphore. * When initializing an unnamed semaphore failed, it would be deleted twice. * The user structure pointer wasn't correctly passed when initializing named semaphores. * When opening a named semaphore failed after it has already been published, it is now unlinked again. * The timeout passed to sem_timedwait() is relative to the Epoch. We need to offset to system time. * Added TODO regarding a per team semaphore limit. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@25345 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/system/kernel/posix/realtime_sem.cpp | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/src/system/kernel/posix/realtime_sem.cpp b/src/system/kernel/posix/realtime_sem.cpp index 75c23ecec8..36ff480610 100644 --- a/src/system/kernel/posix/realtime_sem.cpp +++ b/src/system/kernel/posix/realtime_sem.cpp @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -46,9 +47,11 @@ public: status_t Init(const char* name, mode_t mode, int32 semCount) { - fName = strdup(name); - if (fName == NULL) - return B_NO_MEMORY; + if (name != NULL) { + fName = strdup(name); + if (fName == NULL) + return B_NO_MEMORY; + } fID = create_sem(semCount, name); if (fID < 0) @@ -171,6 +174,7 @@ public: return ENOENT; // does not exist yet -- create +// TODO: Enforce per team semaphore limit! sem = new(std::nothrow) SemInfo; if (sem == NULL) return B_NO_MEMORY; @@ -362,16 +366,15 @@ struct realtime_sem_context { status_t CreateAnonymousSem(uint32 semCount, int& _id) { +// TODO: Enforce per team semaphore limit! SemInfo* sem = new(std::nothrow) SemInfo; if (sem == NULL) return B_NO_MEMORY; ObjectDeleter semDeleter(sem); status_t error = sem->Init(NULL, 0, semCount); - if (error != B_OK) { - delete sem; + if (error != B_OK) return error; - } TeamSemInfo* teamSem = new(std::nothrow) TeamSemInfo(sem, NULL); if (teamSem == NULL) @@ -414,15 +417,19 @@ struct realtime_sem_context { } // not open yet -- create a new team sem - teamSem = new(std::nothrow) TeamSemInfo(sem, NULL); + teamSem = new(std::nothrow) TeamSemInfo(sem, userSem); if (teamSem == NULL) { sem->ReleaseReference(); + if (_created) + sSemTable.UnlinkSem(name); return B_NO_MEMORY; } error = fSemaphores.Insert(teamSem); if (error != B_OK) { delete teamSem; + if (_created) + sSemTable.UnlinkSem(name); return error; } @@ -469,7 +476,8 @@ struct realtime_sem_context { error = acquire_sem_etc(id, 1, B_CAN_INTERRUPT, 0); } else { error = acquire_sem_etc(id, 1, B_CAN_INTERRUPT | B_ABSOLUTE_TIMEOUT, - timeout); + timeout - rtc_boot_time()); + // The given absolute timeout is relative to the Epoch. } return error == B_BAD_SEM_ID ? B_BAD_VALUE : error;