Work in progress towards cleaning up the directwindow server code:

Renamed direct_window_data to DirectWindowData and turned it into a
class.
Encapsulated some functionality inside the DirectWindowData class.
No functional change (yet).
More to come.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@32374 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Stefano Ceccherini
2009-08-14 16:34:55 +00:00
parent d61def1d46
commit 3e20b06294
2 changed files with 97 additions and 68 deletions
+94 -65
View File
@@ -6,7 +6,7 @@
* DarkWyrm <[email protected]> * DarkWyrm <[email protected]>
* Adrian Oanca <[email protected]> * Adrian Oanca <[email protected]>
* Stephan Aßmus <[email protected]> * Stephan Aßmus <[email protected]>
* Stefano Ceccherini ([email protected]) * Stefano Ceccherini <[email protected]>
* Axel Dörfler, [email protected] * Axel Dörfler, [email protected]
* Artur Wyszynski <[email protected]> * Artur Wyszynski <[email protected]>
* Philippe Saint-Pierre, [email protected] * Philippe Saint-Pierre, [email protected]
@@ -120,63 +120,125 @@ static profile sRedrawProcessingTime;
#endif #endif
struct direct_window_data { class DirectWindowData {
direct_window_data(); public:
~direct_window_data(); DirectWindowData();
~DirectWindowData();
status_t InitCheck() const; status_t InitCheck() const;
sem_id sem; status_t GetSyncData(direct_window_sync_data &data) const;
sem_id sem_ack; status_t SyncronizeWithClient();
area_id area;
bool SetState(const direct_buffer_state &bufferState,
const direct_driver_state &driverState);
BRect old_window_frame; BRect old_window_frame;
direct_buffer_info *buffer_info; direct_buffer_info *buffer_info;
bool started; bool started;
private:
sem_id fSem;
sem_id fAcknowledgeSem;
area_id fBufferArea;
}; };
direct_window_data::direct_window_data() DirectWindowData::DirectWindowData()
: :
sem(-1),
sem_ack(-1),
area(-1),
buffer_info(NULL), buffer_info(NULL),
started(false) started(false),
fSem(-1),
fAcknowledgeSem(-1),
fBufferArea(-1)
{ {
area = create_area("direct area", (void **)&buffer_info, fBufferArea = create_area("direct area", (void **)&buffer_info,
B_ANY_ADDRESS, B_PAGE_SIZE, B_NO_LOCK, B_READ_WRITE); B_ANY_ADDRESS, B_PAGE_SIZE, B_NO_LOCK, B_READ_WRITE);
sem = create_sem(0, "direct sem"); buffer_info->buffer_state = B_DIRECT_STOP;
sem_ack = create_sem(0, "direct sem ack"); fSem = create_sem(0, "direct sem");
fAcknowledgeSem = create_sem(0, "direct sem ack");
} }
direct_window_data::~direct_window_data() DirectWindowData::~DirectWindowData()
{ {
// this should make the client die in case it's still running // this should make the client die in case it's still running
buffer_info->bits = NULL; buffer_info->bits = NULL;
buffer_info->bytes_per_row = 0; buffer_info->bytes_per_row = 0;
delete_area(area); delete_area(fBufferArea);
delete_sem(sem); delete_sem(fSem);
delete_sem(sem_ack); delete_sem(fAcknowledgeSem);
} }
status_t status_t
direct_window_data::InitCheck() const DirectWindowData::InitCheck() const
{ {
if (area < B_OK) if (fBufferArea < B_OK)
return area; return fBufferArea;
if (sem < B_OK) if (fSem < B_OK)
return sem; return fSem;
if (sem_ack < B_OK) if (fAcknowledgeSem < B_OK)
return sem_ack; return fAcknowledgeSem;
return B_OK; return B_OK;
} }
status_t
DirectWindowData::GetSyncData(direct_window_sync_data &data) const
{
data.area = fBufferArea;
data.disable_sem = fSem;
data.disable_sem_ack = fAcknowledgeSem;
return B_OK;
}
status_t
DirectWindowData::SyncronizeWithClient()
{
// Releasing this semaphore causes the client to call
// BDirectWindow::DirectConnected()
status_t status = release_sem(fSem);
if (status < B_OK)
return status;
// Wait with a timeout of half a second until the client exits
// from its DirectConnected() implementation
do {
status = acquire_sem_etc(fAcknowledgeSem, 1, B_TIMEOUT, 500000);
} while (status == B_INTERRUPTED);
return status;
}
bool
DirectWindowData::SetState(const direct_buffer_state &bufferState,
const direct_driver_state &driverState)
{
// Don't issue a DirectConnected() notification
// if the connection is stopped, and we are called
// with bufferState == B_DIRECT_MODIFY.
if ((buffer_info->buffer_state & B_DIRECT_MODE_MASK) == B_DIRECT_STOP
&& (bufferState & B_DIRECT_MODE_MASK) != B_DIRECT_START)
return false;
if (bufferState != -1)
buffer_info->buffer_state = bufferState;
if (driverState != -1)
buffer_info->driver_state = driverState;
started = true;
return true;
}
// #pragma mark - // #pragma mark -
@@ -1118,11 +1180,8 @@ ServerWindow::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
fLink.StartMessage(status); fLink.StartMessage(status);
if (status == B_OK) { if (status == B_OK) {
struct direct_window_sync_data syncData = { struct direct_window_sync_data syncData;
fDirectWindowData->area, fDirectWindowData->GetSyncData(syncData);
fDirectWindowData->sem,
fDirectWindowData->sem_ack
};
fLink.Attach(&syncData, sizeof(syncData)); fLink.Attach(&syncData, sizeof(syncData));
} }
@@ -3483,7 +3542,7 @@ ServerWindow::_EnableDirectWindowMode()
return B_ERROR; return B_ERROR;
} }
fDirectWindowData = new (nothrow) direct_window_data; fDirectWindowData = new (nothrow) DirectWindowData;
if (fDirectWindowData == NULL) if (fDirectWindowData == NULL)
return B_NO_MEMORY; return B_NO_MEMORY;
@@ -3510,26 +3569,9 @@ ServerWindow::HandleDirectConnection(int32 bufferState, int32 driverState)
&& (bufferState & B_DIRECT_MODE_MASK) != B_DIRECT_START)) && (bufferState & B_DIRECT_MODE_MASK) != B_DIRECT_START))
return; return;
// Don't issue a DirectConnected() notification if (!fDirectWindowData->SetState((direct_buffer_state)bufferState,
// if the connection is stopped, and we are called (direct_driver_state)driverState))
// with bufferState == B_DIRECT_MODIFY.
if ((fDirectWindowData->buffer_info->buffer_state & B_DIRECT_MODE_MASK)
== B_DIRECT_STOP
&& (bufferState & B_DIRECT_MODE_MASK) != B_DIRECT_START) {
return; return;
}
fDirectWindowData->started = true;
if (bufferState != -1) {
fDirectWindowData->buffer_info->buffer_state
= (direct_buffer_state)bufferState;
}
if (driverState != -1) {
fDirectWindowData->buffer_info->driver_state
= (direct_driver_state)driverState;
}
if ((bufferState & B_DIRECT_MODE_MASK) != B_DIRECT_STOP) { if ((bufferState & B_DIRECT_MODE_MASK) != B_DIRECT_STOP) {
// TODO: Locking ? // TODO: Locking ?
@@ -3591,20 +3633,7 @@ ServerWindow::HandleDirectConnection(int32 bufferState, int32 driverState)
} }
} }
// Releasing this semaphore causes the client to call status_t status = fDirectWindowData->SyncronizeWithClient();
// BDirectWindow::DirectConnected()
release_sem(fDirectWindowData->sem);
// TODO: Waiting half a second in the ServerWindow thread is not a problem,
// but since we are called from the Desktop's thread too, very bad things
// could happen.
// Find some way to call this method only within ServerWindow's thread
// (messaging ?)
status_t status;
do {
status = acquire_sem_etc(fDirectWindowData->sem_ack, 1, B_TIMEOUT,
500000);
} while (status == B_INTERRUPTED);
if (status != B_OK) { if (status != B_OK) {
// The client application didn't release the semaphore // The client application didn't release the semaphore
+2 -2
View File
@@ -40,7 +40,7 @@ class Window;
class Workspace; class Workspace;
class View; class View;
class ServerPicture; class ServerPicture;
struct direct_window_data; class DirectWindowData;
struct window_info; struct window_info;
#define AS_UPDATE_DECORATOR 'asud' #define AS_UPDATE_DECORATOR 'asud'
@@ -168,7 +168,7 @@ private:
BRegion fCurrentDrawingRegion; BRegion fCurrentDrawingRegion;
bool fCurrentDrawingRegionValid; bool fCurrentDrawingRegionValid;
direct_window_data* fDirectWindowData; DirectWindowData* fDirectWindowData;
window_feel fDirectWindowFeel; window_feel fDirectWindowFeel;
}; };