* Improved initialization.

* The counter semaphore is now only released when writing a command into
  an formerly empty area. The userland part is aware of that. :-)


git-svn-id: file:///srv/svn/repos/haiku/trunk/current@11026 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold
2005-01-25 14:51:06 +00:00
parent d7b6591345
commit 27bd55fdf3
2 changed files with 28 additions and 12 deletions
+26 -10
View File
@@ -8,6 +8,7 @@
#include <new> #include <new>
#include <AutoDeleter.h> #include <AutoDeleter.h>
#include <KernelExport.h>
#include <KMessage.h> #include <KMessage.h>
#include <messaging.h> #include <messaging.h>
#include <MessagingServiceDefs.h> #include <MessagingServiceDefs.h>
@@ -27,7 +28,17 @@ init_messaging_service()
if (!sMessagingService) if (!sMessagingService)
sMessagingService = new(buffer) MessagingService; sMessagingService = new(buffer) MessagingService;
return sMessagingService->InitCheck(); status_t error = sMessagingService->InitCheck();
// cleanup on error
if (error != B_OK) {
dprintf("ERROR: Failed to init messaging service: %s\n",
strerror(error));
sMessagingService->~MessagingService();
sMessagingService = NULL;
}
return error;
} }
// _user_register_messaging_service // _user_register_messaging_service
@@ -36,7 +47,8 @@ init_messaging_service()
\param lockingSem A semaphore used for locking the shared data. Semaphore \param lockingSem A semaphore used for locking the shared data. Semaphore
counter must be initialized to 0. counter must be initialized to 0.
\param counterSem A semaphore released every time the kernel pushes a \param counterSem A semaphore released every time the kernel pushes a
command. Semaphore counter must be initialized to 0. command into an empty area. Semaphore counter must be initialized
to 0.
\return \return
- The ID of the kernel area used for communication, if everything went fine, - The ID of the kernel area used for communication, if everything went fine,
- an error code otherwise. - an error code otherwise.
@@ -212,7 +224,8 @@ MessagingArea::Size() const
// AllocateCommand // AllocateCommand
void * void *
MessagingArea::AllocateCommand(uint32 commandWhat, int32 dataSize) MessagingArea::AllocateCommand(uint32 commandWhat, int32 dataSize,
bool &wasEmpty)
{ {
int32 size = sizeof(messaging_command) + dataSize; int32 size = sizeof(messaging_command) + dataSize;
@@ -224,7 +237,8 @@ MessagingArea::AllocateCommand(uint32 commandWhat, int32 dataSize)
// the simple case first: the area is empty // the simple case first: the area is empty
int32 commandOffset; int32 commandOffset;
if (fHeader->command_count == 0) { wasEmpty = (fHeader->command_count == 0);
if (wasEmpty) {
commandOffset = startOffset; commandOffset = startOffset;
// update the header // update the header
@@ -429,7 +443,7 @@ MessagingService::UnregisterService()
// delete all areas // delete all areas
while (fFirstArea) { while (fFirstArea) {
MessagingArea *area = fFirstArea; MessagingArea *area = fFirstArea;
fFirstArea = area; fFirstArea = area->NextArea();
delete area; delete area;
} }
fLastArea = NULL; fLastArea = NULL;
@@ -456,8 +470,9 @@ MessagingService::SendMessage(const void *message, int32 messageSize,
// allocate space for the command // allocate space for the command
MessagingArea *area; MessagingArea *area;
void *data; void *data;
bool wasEmpty;
status_t error = _AllocateCommand(MESSAGING_COMMAND_SEND_MESSAGE, dataSize, status_t error = _AllocateCommand(MESSAGING_COMMAND_SEND_MESSAGE, dataSize,
area, data); area, data, wasEmpty);
if (error != B_OK) if (error != B_OK)
return error; return error;
@@ -471,7 +486,8 @@ MessagingService::SendMessage(const void *message, int32 messageSize,
// shoot // shoot
area->Unlock(); area->Unlock();
area->CommitCommand(); if (wasEmpty)
area->CommitCommand();
return B_OK; return B_OK;
} }
@@ -479,7 +495,7 @@ MessagingService::SendMessage(const void *message, int32 messageSize,
// _AllocateCommand // _AllocateCommand
status_t status_t
MessagingService::_AllocateCommand(int32 commandWhat, int32 size, MessagingService::_AllocateCommand(int32 commandWhat, int32 size,
MessagingArea *&area, void *&data) MessagingArea *&area, void *&data, bool &wasEmpty)
{ {
if (!fFirstArea) if (!fFirstArea)
return B_NO_INIT; return B_NO_INIT;
@@ -507,7 +523,7 @@ MessagingService::_AllocateCommand(int32 commandWhat, int32 size,
// allocate space for the command in the last area // allocate space for the command in the last area
area = fLastArea; area = fLastArea;
area->Lock(); area->Lock();
data = area->AllocateCommand(commandWhat, size); data = area->AllocateCommand(commandWhat, size, wasEmpty);
if (!data) { if (!data) {
// not enough space in the last area: create a new area or reuse a // not enough space in the last area: create a new area or reuse a
@@ -528,7 +544,7 @@ MessagingService::_AllocateCommand(int32 commandWhat, int32 size,
fLastArea = area; fLastArea = area;
// allocate space for the command // allocate space for the command
data = area->AllocateCommand(commandWhat, size); data = area->AllocateCommand(commandWhat, size, wasEmpty);
if (!data) { if (!data) {
// that should never happen // that should never happen
+2 -2
View File
@@ -31,7 +31,7 @@ public:
area_id ID() const; area_id ID() const;
int32 Size() const; int32 Size() const;
void *AllocateCommand(uint32 commandWhat, int32 dataSize); void *AllocateCommand(uint32 commandWhat, int32 dataSize, bool &wasEmpty);
void CommitCommand(); void CommitCommand();
void SetNextArea(MessagingArea *area); void SetNextArea(MessagingArea *area);
@@ -70,7 +70,7 @@ public:
private: private:
status_t _AllocateCommand(int32 commandWhat, int32 size, status_t _AllocateCommand(int32 commandWhat, int32 size,
MessagingArea *&area, void *&data); MessagingArea *&area, void *&data, bool &wasEmpty);
BLocker fLock; BLocker fLock;
team_id fServerTeam; team_id fServerTeam;