* 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:
parent
d7b6591345
commit
27bd55fdf3
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue