* 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

View File

@ -8,6 +8,7 @@
#include <new>
#include <AutoDeleter.h>
#include <KernelExport.h>
#include <KMessage.h>
#include <messaging.h>
#include <MessagingServiceDefs.h>
@ -27,7 +28,17 @@ init_messaging_service()
if (!sMessagingService)
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
@ -36,7 +47,8 @@ init_messaging_service()
\param lockingSem A semaphore used for locking the shared data. Semaphore
counter must be initialized to 0.
\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
- The ID of the kernel area used for communication, if everything went fine,
- an error code otherwise.
@ -212,7 +224,8 @@ MessagingArea::Size() const
// AllocateCommand
void *
MessagingArea::AllocateCommand(uint32 commandWhat, int32 dataSize)
MessagingArea::AllocateCommand(uint32 commandWhat, int32 dataSize,
bool &wasEmpty)
{
int32 size = sizeof(messaging_command) + dataSize;
@ -224,7 +237,8 @@ MessagingArea::AllocateCommand(uint32 commandWhat, int32 dataSize)
// the simple case first: the area is empty
int32 commandOffset;
if (fHeader->command_count == 0) {
wasEmpty = (fHeader->command_count == 0);
if (wasEmpty) {
commandOffset = startOffset;
// update the header
@ -429,7 +443,7 @@ MessagingService::UnregisterService()
// delete all areas
while (fFirstArea) {
MessagingArea *area = fFirstArea;
fFirstArea = area;
fFirstArea = area->NextArea();
delete area;
}
fLastArea = NULL;
@ -456,8 +470,9 @@ MessagingService::SendMessage(const void *message, int32 messageSize,
// allocate space for the command
MessagingArea *area;
void *data;
bool wasEmpty;
status_t error = _AllocateCommand(MESSAGING_COMMAND_SEND_MESSAGE, dataSize,
area, data);
area, data, wasEmpty);
if (error != B_OK)
return error;
@ -471,6 +486,7 @@ MessagingService::SendMessage(const void *message, int32 messageSize,
// shoot
area->Unlock();
if (wasEmpty)
area->CommitCommand();
return B_OK;
@ -479,7 +495,7 @@ MessagingService::SendMessage(const void *message, int32 messageSize,
// _AllocateCommand
status_t
MessagingService::_AllocateCommand(int32 commandWhat, int32 size,
MessagingArea *&area, void *&data)
MessagingArea *&area, void *&data, bool &wasEmpty)
{
if (!fFirstArea)
return B_NO_INIT;
@ -507,7 +523,7 @@ MessagingService::_AllocateCommand(int32 commandWhat, int32 size,
// allocate space for the command in the last area
area = fLastArea;
area->Lock();
data = area->AllocateCommand(commandWhat, size);
data = area->AllocateCommand(commandWhat, size, wasEmpty);
if (!data) {
// 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;
// allocate space for the command
data = area->AllocateCommand(commandWhat, size);
data = area->AllocateCommand(commandWhat, size, wasEmpty);
if (!data) {
// that should never happen

View File

@ -31,7 +31,7 @@ public:
area_id ID() const;
int32 Size() const;
void *AllocateCommand(uint32 commandWhat, int32 dataSize);
void *AllocateCommand(uint32 commandWhat, int32 dataSize, bool &wasEmpty);
void CommitCommand();
void SetNextArea(MessagingArea *area);
@ -70,7 +70,7 @@ public:
private:
status_t _AllocateCommand(int32 commandWhat, int32 size,
MessagingArea *&area, void *&data);
MessagingArea *&area, void *&data, bool &wasEmpty);
BLocker fLock;
team_id fServerTeam;