* 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
This commit is contained in:
@@ -15,6 +15,7 @@
|
|||||||
#include <fs/KPath.h>
|
#include <fs/KPath.h>
|
||||||
#include <kernel.h>
|
#include <kernel.h>
|
||||||
#include <lock.h>
|
#include <lock.h>
|
||||||
|
#include <real_time_clock.h>
|
||||||
#include <syscall_restart.h>
|
#include <syscall_restart.h>
|
||||||
#include <team.h>
|
#include <team.h>
|
||||||
#include <thread.h>
|
#include <thread.h>
|
||||||
@@ -46,9 +47,11 @@ public:
|
|||||||
|
|
||||||
status_t Init(const char* name, mode_t mode, int32 semCount)
|
status_t Init(const char* name, mode_t mode, int32 semCount)
|
||||||
{
|
{
|
||||||
fName = strdup(name);
|
if (name != NULL) {
|
||||||
if (fName == NULL)
|
fName = strdup(name);
|
||||||
return B_NO_MEMORY;
|
if (fName == NULL)
|
||||||
|
return B_NO_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
fID = create_sem(semCount, name);
|
fID = create_sem(semCount, name);
|
||||||
if (fID < 0)
|
if (fID < 0)
|
||||||
@@ -171,6 +174,7 @@ public:
|
|||||||
return ENOENT;
|
return ENOENT;
|
||||||
|
|
||||||
// does not exist yet -- create
|
// does not exist yet -- create
|
||||||
|
// TODO: Enforce per team semaphore limit!
|
||||||
sem = new(std::nothrow) SemInfo;
|
sem = new(std::nothrow) SemInfo;
|
||||||
if (sem == NULL)
|
if (sem == NULL)
|
||||||
return B_NO_MEMORY;
|
return B_NO_MEMORY;
|
||||||
@@ -362,16 +366,15 @@ struct realtime_sem_context {
|
|||||||
|
|
||||||
status_t CreateAnonymousSem(uint32 semCount, int& _id)
|
status_t CreateAnonymousSem(uint32 semCount, int& _id)
|
||||||
{
|
{
|
||||||
|
// TODO: Enforce per team semaphore limit!
|
||||||
SemInfo* sem = new(std::nothrow) SemInfo;
|
SemInfo* sem = new(std::nothrow) SemInfo;
|
||||||
if (sem == NULL)
|
if (sem == NULL)
|
||||||
return B_NO_MEMORY;
|
return B_NO_MEMORY;
|
||||||
ObjectDeleter<SemInfo> semDeleter(sem);
|
ObjectDeleter<SemInfo> semDeleter(sem);
|
||||||
|
|
||||||
status_t error = sem->Init(NULL, 0, semCount);
|
status_t error = sem->Init(NULL, 0, semCount);
|
||||||
if (error != B_OK) {
|
if (error != B_OK)
|
||||||
delete sem;
|
|
||||||
return error;
|
return error;
|
||||||
}
|
|
||||||
|
|
||||||
TeamSemInfo* teamSem = new(std::nothrow) TeamSemInfo(sem, NULL);
|
TeamSemInfo* teamSem = new(std::nothrow) TeamSemInfo(sem, NULL);
|
||||||
if (teamSem == NULL)
|
if (teamSem == NULL)
|
||||||
@@ -414,15 +417,19 @@ struct realtime_sem_context {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// not open yet -- create a new team sem
|
// 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) {
|
if (teamSem == NULL) {
|
||||||
sem->ReleaseReference();
|
sem->ReleaseReference();
|
||||||
|
if (_created)
|
||||||
|
sSemTable.UnlinkSem(name);
|
||||||
return B_NO_MEMORY;
|
return B_NO_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
error = fSemaphores.Insert(teamSem);
|
error = fSemaphores.Insert(teamSem);
|
||||||
if (error != B_OK) {
|
if (error != B_OK) {
|
||||||
delete teamSem;
|
delete teamSem;
|
||||||
|
if (_created)
|
||||||
|
sSemTable.UnlinkSem(name);
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -469,7 +476,8 @@ struct realtime_sem_context {
|
|||||||
error = acquire_sem_etc(id, 1, B_CAN_INTERRUPT, 0);
|
error = acquire_sem_etc(id, 1, B_CAN_INTERRUPT, 0);
|
||||||
} else {
|
} else {
|
||||||
error = acquire_sem_etc(id, 1, B_CAN_INTERRUPT | B_ABSOLUTE_TIMEOUT,
|
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;
|
return error == B_BAD_SEM_ID ? B_BAD_VALUE : error;
|
||||||
|
|||||||
Reference in New Issue
Block a user