* Added some padding to the sem_t structure.

* Changed the semantics of unnamed semaphores. Before parent and child
  of a fork() would always share an earlier created semaphore. Now we do
  that only, if the "shared" parameter of sem_init() was true. That's
  still not quite the behavior Linux and Solaris have, but should be
  perfectly fine with how reasonable code would use the API.
* There's a global table for shared unnamed semaphores now. ATM a
  semaphore is leaked when no one explicitly destroys it (just as with
  named sems).
* Enforce per-team and global semaphore number limits.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@25362 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold
2008-05-08 01:39:49 +00:00
parent 01b1098795
commit 3dfe682f55
4 changed files with 382 additions and 88 deletions
+3 -1
View File
@@ -5,12 +5,14 @@
#ifndef _SEMAPHORE_H_ #ifndef _SEMAPHORE_H_
#define _SEMAPHORE_H_ #define _SEMAPHORE_H_
#include <stdint.h>
#include <sys/cdefs.h> #include <sys/cdefs.h>
#include <time.h> #include <time.h>
typedef struct { typedef struct {
int id; int32_t id;
int32_t _padding[3];
} sem_t; } sem_t;
#define SEM_FAILED ((sem_t*)(long)-1) #define SEM_FAILED ((sem_t*)(long)-1)
+3 -3
View File
@@ -77,9 +77,9 @@ extern status_t _kern_get_next_sem_info(team_id team, int32 *cookie,
extern status_t _kern_set_sem_owner(sem_id id, team_id proc); extern status_t _kern_set_sem_owner(sem_id id, team_id proc);
/* POSIX realtime sem syscalls */ /* POSIX realtime sem syscalls */
extern status_t _kern_realtime_sem_open(const char* name, int openFlags, extern status_t _kern_realtime_sem_open(const char* name,
mode_t mode, uint32 semCount, sem_t* userSem, int openFlagsOrShared, mode_t mode, uint32 semCount,
sem_t** _usedUserSem); sem_t* userSem, sem_t** _usedUserSem);
extern status_t _kern_realtime_sem_close(sem_id semID, extern status_t _kern_realtime_sem_close(sem_id semID,
sem_t** _deleteUserSem); sem_t** _deleteUserSem);
extern status_t _kern_realtime_sem_unlink(const char* name); extern status_t _kern_realtime_sem_unlink(const char* name);
+374 -82
View File
@@ -29,33 +29,61 @@ class SemInfo {
public: public:
SemInfo() SemInfo()
: :
fName(NULL), fSemaphoreID(-1)
fRefCount(1),
fID(-1)
{ {
} }
~SemInfo() virtual ~SemInfo()
{
if (fSemaphoreID >= 0)
delete_sem(fSemaphoreID);
}
sem_id SemaphoreID() const { return fSemaphoreID; }
status_t Init(int32 semCount, const char* name)
{
fSemaphoreID = create_sem(semCount, name);
if (fSemaphoreID < 0)
return fSemaphoreID;
return B_OK;
}
virtual sem_id ID() const = 0;
virtual SemInfo* Clone() = 0;
virtual void Delete() = 0;
private:
sem_id fSemaphoreID;
};
class NamedSem : public SemInfo {
public:
NamedSem()
:
fName(NULL),
fRefCount(1)
{
}
virtual ~NamedSem()
{ {
free(fName); free(fName);
if (fID >= 0)
delete_sem(fID);
} }
const char* Name() const { return fName; } const char* Name() const { return fName; }
sem_id ID() const { return fID; }
status_t Init(const char* name, mode_t mode, int32 semCount) status_t Init(const char* name, mode_t mode, int32 semCount)
{ {
if (name != NULL) { status_t error = SemInfo::Init(semCount, name);
fName = strdup(name); if (error != B_OK)
if (fName == NULL) return error;
return B_NO_MEMORY;
}
fID = create_sem(semCount, name); fName = strdup(name);
if (fID < 0) if (fName == NULL)
return fID; return B_NO_MEMORY;
fUID = geteuid(); fUID = geteuid();
fGID = getegid(); fGID = getegid();
@@ -91,7 +119,23 @@ public:
return false; return false;
} }
HashTableLink<SemInfo>* HashTableLink() virtual sem_id ID() const
{
return SemaphoreID();
}
virtual SemInfo* Clone()
{
AcquireReference();
return this;
}
virtual void Delete()
{
ReleaseReference();
}
HashTableLink<NamedSem>* HashTableLink()
{ {
return &fHashLink; return &fHashLink;
} }
@@ -99,64 +143,192 @@ public:
private: private:
char* fName; char* fName;
vint32 fRefCount; vint32 fRefCount;
sem_id fID;
uid_t fUID; uid_t fUID;
gid_t fGID; gid_t fGID;
mode_t fPermissions; mode_t fPermissions;
::HashTableLink<SemInfo> fHashLink; ::HashTableLink<NamedSem> fHashLink;
};
class UnnamedSem : public SemInfo {
public:
UnnamedSem()
:
fID(0)
{
}
virtual ~UnnamedSem()
{
}
status_t Init(int32 semCount, const char* name)
{
return SemInfo::Init(semCount, name);
}
void SetID(sem_id id)
{
fID = id;
}
virtual sem_id ID() const
{
return fID;
}
virtual SemInfo* Clone()
{
sem_info info;
if (get_sem_info(SemaphoreID(), &info) != B_OK)
return NULL;
UnnamedSem* clone = new(std::nothrow) UnnamedSem;
if (clone == NULL)
return NULL;
if (clone->Init(info.count, info.name) != B_OK) {
delete clone;
return NULL;
}
clone->SetID(fID);
return clone;
}
virtual void Delete()
{
delete this;
}
private:
sem_id fID;
};
class UnnamedSharedSem : public SemInfo {
public:
UnnamedSharedSem()
{
}
virtual ~UnnamedSharedSem()
{
}
status_t Init(int32 semCount, const char* name)
{
return SemInfo::Init(semCount, name);
}
virtual sem_id ID() const
{
return SemaphoreID();
}
virtual SemInfo* Clone()
{
// Can't be cloned.
return NULL;
}
virtual void Delete()
{
delete this;
}
HashTableLink<UnnamedSharedSem>* HashTableLink()
{
return &fHashLink;
}
private:
::HashTableLink<UnnamedSharedSem> fHashLink;
}; };
struct NamedSemHashDefinition { struct NamedSemHashDefinition {
typedef const char* KeyType; typedef const char* KeyType;
typedef SemInfo ValueType; typedef NamedSem ValueType;
size_t HashKey(const KeyType& key) const size_t HashKey(const KeyType& key) const
{ {
return hash_hash_string(key); return hash_hash_string(key);
} }
size_t Hash(SemInfo* semaphore) const size_t Hash(NamedSem* semaphore) const
{ {
return HashKey(semaphore->Name()); return HashKey(semaphore->Name());
} }
bool Compare(const KeyType& key, SemInfo* semaphore) const bool Compare(const KeyType& key, NamedSem* semaphore) const
{ {
return strcmp(key, semaphore->Name()) == 0; return strcmp(key, semaphore->Name()) == 0;
} }
HashTableLink<SemInfo>* GetLink(SemInfo* semaphore) const HashTableLink<NamedSem>* GetLink(NamedSem* semaphore) const
{ {
return semaphore->HashTableLink(); return semaphore->HashTableLink();
} }
}; };
class GlobalRealtimeSemTable { struct UnnamedSemHashDefinition {
public: typedef sem_id KeyType;
GlobalRealtimeSemTable() typedef UnnamedSharedSem ValueType;
size_t HashKey(const KeyType& key) const
{ {
mutex_init(&fLock, "global realtime sem table"); return (size_t)key;
} }
~GlobalRealtimeSemTable() size_t Hash(UnnamedSharedSem* semaphore) const
{
return HashKey(semaphore->SemaphoreID());
}
bool Compare(const KeyType& key, UnnamedSharedSem* semaphore) const
{
return key == semaphore->SemaphoreID();
}
HashTableLink<UnnamedSharedSem>* GetLink(UnnamedSharedSem* semaphore) const
{
return semaphore->HashTableLink();
}
};
class GlobalSemTable {
public:
GlobalSemTable()
:
fSemaphoreCount(0)
{
mutex_init(&fLock, "global named sem table");
}
~GlobalSemTable()
{ {
mutex_destroy(&fLock); mutex_destroy(&fLock);
} }
status_t Init() status_t Init()
{ {
return fSemaphores.InitCheck(); status_t error = fNamedSemaphores.InitCheck();
if (error != B_OK)
return error;
return fUnnamedSemaphores.InitCheck();
} }
status_t OpenSem(const char* name, int openFlags, mode_t mode, status_t OpenNamedSem(const char* name, int openFlags, mode_t mode,
uint32 semCount, SemInfo*& _sem, bool& _created) uint32 semCount, NamedSem*& _sem, bool& _created)
{ {
MutexLocker _(fLock); MutexLocker _(fLock);
SemInfo* sem = fSemaphores.Lookup(name); NamedSem* sem = fNamedSemaphores.Lookup(name);
if (sem != NULL) { if (sem != NULL) {
if ((openFlags & O_EXCL) != 0) if ((openFlags & O_EXCL) != 0)
return EEXIST; return EEXIST;
@@ -174,8 +346,10 @@ public:
return ENOENT; return ENOENT;
// does not exist yet -- create // does not exist yet -- create
// TODO: Enforce per team semaphore limit! if (fSemaphoreCount >= MAX_POSIX_SEMS)
sem = new(std::nothrow) SemInfo; return ENOSPC;
sem = new(std::nothrow) NamedSem;
if (sem == NULL) if (sem == NULL)
return B_NO_MEMORY; return B_NO_MEMORY;
@@ -185,7 +359,7 @@ public:
return error; return error;
} }
error = fSemaphores.Insert(sem); error = fNamedSemaphores.Insert(sem);
if (error != B_OK) { if (error != B_OK) {
delete sem; delete sem;
return error; return error;
@@ -194,38 +368,92 @@ public:
// add one reference for the table // add one reference for the table
sem->AcquireReference(); sem->AcquireReference();
fSemaphoreCount++;
_sem = sem; _sem = sem;
_created = true; _created = true;
return B_OK; return B_OK;
} }
status_t UnlinkSem(const char* name) status_t UnlinkNamedSem(const char* name)
{ {
MutexLocker _(fLock); MutexLocker _(fLock);
SemInfo* sem = fSemaphores.Lookup(name); NamedSem* sem = fNamedSemaphores.Lookup(name);
if (sem == NULL) if (sem == NULL)
return ENOENT; return ENOENT;
if (!sem->HasPermissions()) if (!sem->HasPermissions())
return EACCES; return EACCES;
fSemaphores.Remove(sem); fNamedSemaphores.Remove(sem);
sem->ReleaseReference(); sem->ReleaseReference();
// release the table reference // release the table reference
fSemaphoreCount--;
return B_OK; return B_OK;
} }
private: status_t CreateUnnamedSem(uint32 semCount, int32_t& _id)
typedef OpenHashTable<NamedSemHashDefinition, true> SemTable; {
MutexLocker _(fLock);
mutex fLock; if (fSemaphoreCount >= MAX_POSIX_SEMS)
SemTable fSemaphores; return ENOSPC;
UnnamedSharedSem* sem = new(std::nothrow) UnnamedSharedSem;
if (sem == NULL)
return B_NO_MEMORY;
status_t error = sem->Init(semCount, "unnamed shared sem");
if (error == B_OK)
error = fUnnamedSemaphores.Insert(sem);
if (error != B_OK) {
delete sem;
return error;
}
fSemaphoreCount++;
_id = sem->SemaphoreID();
return B_OK;
}
status_t DeleteUnnamedSem(sem_id id)
{
MutexLocker _(fLock);
UnnamedSharedSem* sem = fUnnamedSemaphores.Lookup(id);
if (sem == NULL)
return B_BAD_VALUE;
fUnnamedSemaphores.Remove(sem);
delete sem;
fSemaphoreCount--;
return B_OK;
}
bool IsUnnamedValidSem(sem_id id)
{
MutexLocker _(fLock);
return fUnnamedSemaphores.Lookup(id) != NULL;
}
private:
typedef OpenHashTable<NamedSemHashDefinition, true> NamedSemTable;
typedef OpenHashTable<UnnamedSemHashDefinition, true> UnnamedSemTable;
mutex fLock;
NamedSemTable fNamedSemaphores;
UnnamedSemTable fUnnamedSemaphores;
int32 fSemaphoreCount;
}; };
static GlobalRealtimeSemTable sSemTable; static GlobalSemTable sSemTable;
class TeamSemInfo { class TeamSemInfo {
@@ -241,10 +469,11 @@ public:
~TeamSemInfo() ~TeamSemInfo()
{ {
if (fSemaphore != NULL) if (fSemaphore != NULL)
fSemaphore->ReleaseReference(); fSemaphore->Delete();
} }
SemInfo* Semaphore() const { return fSemaphore; } sem_id ID() const { return fSemaphore->ID(); }
sem_id SemaphoreID() const { return fSemaphore->SemaphoreID(); }
sem_t* UserSemaphore() const { return fUserSemaphore; } sem_t* UserSemaphore() const { return fUserSemaphore; }
void Open() void Open()
@@ -259,15 +488,19 @@ public:
TeamSemInfo* Clone() const TeamSemInfo* Clone() const
{ {
TeamSemInfo* sem = new(std::nothrow) TeamSemInfo(fSemaphore, SemInfo* sem = fSemaphore->Clone();
fUserSemaphore);
if (sem == NULL) if (sem == NULL)
return NULL; return NULL;
sem->fOpenCount = fOpenCount; TeamSemInfo* clone = new(std::nothrow) TeamSemInfo(sem, fUserSemaphore);
fSemaphore->AcquireReference(); if (clone == NULL) {
sem->Delete();
return NULL;
}
return sem; clone->fOpenCount = fOpenCount;
return clone;
} }
HashTableLink<TeamSemInfo>* HashTableLink() HashTableLink<TeamSemInfo>* HashTableLink()
@@ -295,12 +528,12 @@ struct TeamSemHashDefinition {
size_t Hash(TeamSemInfo* semaphore) const size_t Hash(TeamSemInfo* semaphore) const
{ {
return HashKey(semaphore->Semaphore()->ID()); return HashKey(semaphore->ID());
} }
bool Compare(const KeyType& key, TeamSemInfo* semaphore) const bool Compare(const KeyType& key, TeamSemInfo* semaphore) const
{ {
return key == semaphore->Semaphore()->ID(); return key == semaphore->ID();
} }
HashTableLink<TeamSemInfo>* GetLink(TeamSemInfo* semaphore) const HashTableLink<TeamSemInfo>* GetLink(TeamSemInfo* semaphore) const
@@ -312,6 +545,8 @@ struct TeamSemHashDefinition {
struct realtime_sem_context { struct realtime_sem_context {
realtime_sem_context() realtime_sem_context()
:
fSemaphoreCount(0)
{ {
mutex_init(&fLock, "realtime sem context"); mutex_init(&fLock, "realtime sem context");
} }
@@ -334,6 +569,7 @@ struct realtime_sem_context {
status_t Init() status_t Init()
{ {
fNextPrivateSemID = -1;
return fSemaphores.InitCheck(); return fSemaphores.InitCheck();
} }
@@ -347,6 +583,8 @@ struct realtime_sem_context {
MutexLocker _(fLock); MutexLocker _(fLock);
context->fNextPrivateSemID = fNextPrivateSemID;
// clone all semaphores // clone all semaphores
SemTable::Iterator it = fSemaphores.GetIterator(); SemTable::Iterator it = fSemaphores.GetIterator();
while (TeamSemInfo* sem = it.Next()) { while (TeamSemInfo* sem = it.Next()) {
@@ -358,21 +596,24 @@ struct realtime_sem_context {
delete clonedSem; delete clonedSem;
return NULL; return NULL;
} }
context->fSemaphoreCount++;
} }
contextDeleter.Detach(); contextDeleter.Detach();
return context; return context;
} }
status_t CreateAnonymousSem(uint32 semCount, int& _id) status_t CreateUnnamedSem(uint32 semCount, bool shared, int32_t& _id)
{ {
// TODO: Enforce per team semaphore limit! if (shared)
SemInfo* sem = new(std::nothrow) SemInfo; return sSemTable.CreateUnnamedSem(semCount, _id);
UnnamedSem* sem = new(std::nothrow) UnnamedSem;
if (sem == NULL) if (sem == NULL)
return B_NO_MEMORY; return B_NO_MEMORY;
ObjectDeleter<SemInfo> semDeleter(sem); ObjectDeleter<UnnamedSem> semDeleter(sem);
status_t error = sem->Init(NULL, 0, semCount); status_t error = sem->Init(semCount, "unnamed sem");
if (error != B_OK) if (error != B_OK)
return error; return error;
@@ -383,23 +624,31 @@ struct realtime_sem_context {
MutexLocker _(fLock); MutexLocker _(fLock);
if (fSemaphoreCount >= MAX_POSIX_SEMS_PER_TEAM) {
delete teamSem;
return ENOSPC;
}
sem->SetID(_NextPrivateSemID());
error = fSemaphores.Insert(teamSem); error = fSemaphores.Insert(teamSem);
if (error != B_OK) { if (error != B_OK) {
delete teamSem; delete teamSem;
return error; return error;
} }
_id = teamSem->Semaphore()->ID(); fSemaphoreCount++;
_id = teamSem->ID();
return B_OK; return B_OK;
} }
status_t OpenSem(const char* name, int openFlags, mode_t mode, status_t OpenSem(const char* name, int openFlags, mode_t mode,
uint32 semCount, sem_t* userSem, sem_t*& _usedUserSem, int& _id, uint32 semCount, sem_t* userSem, sem_t*& _usedUserSem, int32_t& _id,
bool& _created) bool& _created)
{ {
SemInfo* sem; NamedSem* sem;
status_t error = sSemTable.OpenSem(name, openFlags, mode, semCount, status_t error = sSemTable.OpenNamedSem(name, openFlags, mode, semCount,
sem, _created); sem, _created);
if (error != B_OK) if (error != B_OK)
return error; return error;
@@ -412,16 +661,25 @@ struct realtime_sem_context {
teamSem->Open(); teamSem->Open();
sem->ReleaseReference(); sem->ReleaseReference();
_usedUserSem = teamSem->UserSemaphore(); _usedUserSem = teamSem->UserSemaphore();
_id = teamSem->Semaphore()->ID(); _id = teamSem->ID();
return B_OK; return B_OK;
} }
// not open yet -- create a new team sem // not open yet -- create a new team sem
// first check the semaphore limit, though
if (fSemaphoreCount >= MAX_POSIX_SEMS_PER_TEAM) {
sem->ReleaseReference();
if (_created)
sSemTable.UnlinkNamedSem(name);
return ENOSPC;
}
teamSem = new(std::nothrow) TeamSemInfo(sem, userSem); teamSem = new(std::nothrow) TeamSemInfo(sem, userSem);
if (teamSem == NULL) { if (teamSem == NULL) {
sem->ReleaseReference(); sem->ReleaseReference();
if (_created) if (_created)
sSemTable.UnlinkSem(name); sSemTable.UnlinkNamedSem(name);
return B_NO_MEMORY; return B_NO_MEMORY;
} }
@@ -429,12 +687,14 @@ struct realtime_sem_context {
if (error != B_OK) { if (error != B_OK) {
delete teamSem; delete teamSem;
if (_created) if (_created)
sSemTable.UnlinkSem(name); sSemTable.UnlinkNamedSem(name);
return error; return error;
} }
fSemaphoreCount++;
_usedUserSem = teamSem->UserSemaphore(); _usedUserSem = teamSem->UserSemaphore();
_id = teamSem->Semaphore()->ID(); _id = teamSem->ID();
return B_OK; return B_OK;
} }
@@ -447,11 +707,12 @@ struct realtime_sem_context {
TeamSemInfo* sem = fSemaphores.Lookup(id); TeamSemInfo* sem = fSemaphores.Lookup(id);
if (sem == NULL) if (sem == NULL)
return B_BAD_VALUE; return sSemTable.DeleteUnnamedSem(id);
if (sem->Close()) { if (sem->Close()) {
// last reference closed // last reference closed
fSemaphores.Remove(sem); fSemaphores.Remove(sem);
fSemaphoreCount--;
deleteUserSem = sem->UserSemaphore(); deleteUserSem = sem->UserSemaphore();
delete sem; delete sem;
} }
@@ -463,8 +724,12 @@ struct realtime_sem_context {
{ {
MutexLocker locker(fLock); MutexLocker locker(fLock);
if (fSemaphores.Lookup(id) == NULL) TeamSemInfo* sem = fSemaphores.Lookup(id);
return B_BAD_VALUE; if (sem == NULL) {
if (!sSemTable.IsUnnamedValidSem(id))
return B_BAD_VALUE;
} else
id = sem->SemaphoreID();
locker.Unlock(); locker.Unlock();
@@ -487,8 +752,12 @@ struct realtime_sem_context {
{ {
MutexLocker locker(fLock); MutexLocker locker(fLock);
if (fSemaphores.Lookup(id) == NULL) TeamSemInfo* sem = fSemaphores.Lookup(id);
return B_BAD_VALUE; if (sem == NULL) {
if (!sSemTable.IsUnnamedValidSem(id))
return B_BAD_VALUE;
} else
id = sem->SemaphoreID();
locker.Unlock(); locker.Unlock();
@@ -500,8 +769,12 @@ struct realtime_sem_context {
{ {
MutexLocker locker(fLock); MutexLocker locker(fLock);
if (fSemaphores.Lookup(id) == NULL) TeamSemInfo* sem = fSemaphores.Lookup(id);
return B_BAD_VALUE; if (sem == NULL) {
if (!sSemTable.IsUnnamedValidSem(id))
return B_BAD_VALUE;
} else
id = sem->SemaphoreID();
locker.Unlock(); locker.Unlock();
@@ -514,11 +787,26 @@ struct realtime_sem_context {
return B_OK; return B_OK;
} }
private:
sem_id _NextPrivateSemID()
{
while (true) {
if (fNextPrivateSemID >= 0)
fNextPrivateSemID = -1;
sem_id id = fNextPrivateSemID--;
if (fSemaphores.Lookup(id) == NULL)
return id;
}
}
private: private:
typedef OpenHashTable<TeamSemHashDefinition, true> SemTable; typedef OpenHashTable<TeamSemHashDefinition, true> SemTable;
mutex fLock; mutex fLock;
SemTable fSemaphores; SemTable fSemaphores;
int32 fSemaphoreCount;
sem_id fNextPrivateSemID;
}; };
@@ -585,9 +873,9 @@ copy_sem_name_to_kernel(const char* userName, KPath& buffer, char*& name)
void void
realtime_sem_init() realtime_sem_init()
{ {
new(&sSemTable) GlobalRealtimeSemTable; new(&sSemTable) GlobalSemTable;
if (sSemTable.Init() != B_OK) if (sSemTable.Init() != B_OK)
panic("realtime_sem_init() failed to init global table"); panic("realtime_sem_init() failed to init global sem table");
} }
@@ -612,23 +900,27 @@ clone_realtime_sem_context(realtime_sem_context* context)
status_t status_t
_user_realtime_sem_open(const char* userName, int openFlags, mode_t mode, _user_realtime_sem_open(const char* userName, int openFlagsOrShared,
uint32 semCount, sem_t* userSem, sem_t** _usedUserSem) mode_t mode, uint32 semCount, sem_t* userSem, sem_t** _usedUserSem)
{ {
realtime_sem_context* context = get_current_team_context(); realtime_sem_context* context = get_current_team_context();
if (context == NULL) if (context == NULL)
return B_NO_MEMORY; return B_NO_MEMORY;
if (semCount > MAX_POSIX_SEM_VALUE)
return B_BAD_VALUE;
// userSem must always be given // userSem must always be given
if (userSem == NULL) if (userSem == NULL)
return B_BAD_VALUE; return B_BAD_VALUE;
if (!IS_USER_ADDRESS(userSem)) if (!IS_USER_ADDRESS(userSem))
return B_BAD_ADDRESS; return B_BAD_ADDRESS;
// anonymous semaphores are less work -- deal with them first // unnamed semaphores are less work -- deal with them first
if (userName == NULL) { if (userName == NULL) {
int id; int32_t id;
status_t error = context->CreateAnonymousSem(semCount, id); status_t error = context->CreateUnnamedSem(semCount, openFlagsOrShared,
id);
if (error != B_OK) if (error != B_OK)
return error; return error;
@@ -657,8 +949,8 @@ _user_realtime_sem_open(const char* userName, int openFlags, mode_t mode,
// open the semaphore // open the semaphore
sem_t* usedUserSem; sem_t* usedUserSem;
bool created; bool created;
int id; int32_t id;
error = context->OpenSem(name, openFlags, mode, semCount, userSem, error = context->OpenSem(name, openFlagsOrShared, mode, semCount, userSem,
usedUserSem, id, created); usedUserSem, id, created);
if (error != B_OK) if (error != B_OK)
return error; return error;
@@ -667,7 +959,7 @@ _user_realtime_sem_open(const char* userName, int openFlags, mode_t mode,
if (user_memcpy(&userSem->id, &id, sizeof(int)) != B_OK if (user_memcpy(&userSem->id, &id, sizeof(int)) != B_OK
|| user_memcpy(_usedUserSem, &usedUserSem, sizeof(sem_t*)) != B_OK) { || user_memcpy(_usedUserSem, &usedUserSem, sizeof(sem_t*)) != B_OK) {
if (created) if (created)
sSemTable.UnlinkSem(name); sSemTable.UnlinkNamedSem(name);
sem_t* dummy; sem_t* dummy;
context->CloseSem(id, dummy); context->CloseSem(id, dummy);
return B_BAD_ADDRESS; return B_BAD_ADDRESS;
@@ -714,7 +1006,7 @@ _user_realtime_sem_unlink(const char* userName)
if (error != B_OK) if (error != B_OK)
return error; return error;
return sSemTable.UnlinkSem(name); return sSemTable.UnlinkNamedSem(name);
} }
+2 -2
View File
@@ -89,8 +89,8 @@ sem_unlink(const char* name)
int int
sem_init(sem_t* semaphore, int shared, unsigned value) sem_init(sem_t* semaphore, int shared, unsigned value)
{ {
RETURN_AND_SET_ERRNO(_kern_realtime_sem_open(NULL, 0, 0, value, semaphore, RETURN_AND_SET_ERRNO(_kern_realtime_sem_open(NULL, shared, 0, value,
NULL)); semaphore, NULL));
} }