Make it possible to properly use operator= on BCursors by making sure the

reference counting is maintained correctly in the app_server. While reviewing
this code, I have my doubts that my previous solution for handling pending
SetViewCursor() calls is always working as it is intended.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@31131 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Stephan Aßmus
2009-06-20 10:10:01 +00:00
parent 76d87570c9
commit 5d62f8e0e5
4 changed files with 116 additions and 31 deletions
+10 -2
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright 2006, Haiku, Inc. All Rights Reserved. * Copyright 2006-2009, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
*/ */
#ifndef _CURSOR_H #ifndef _CURSOR_H
@@ -13,12 +13,18 @@
class BCursor : BArchivable { class BCursor : BArchivable {
public: public:
BCursor(const void* cursorData); BCursor(const void* cursorData);
BCursor(const BCursor& other);
BCursor(BMessage* data); BCursor(BMessage* data);
virtual ~BCursor(); virtual ~BCursor();
virtual status_t Archive(BMessage* archive, bool deep = true) const; virtual status_t Archive(BMessage* archive,
bool deep = true) const;
static BArchivable* Instantiate(BMessage* archive); static BArchivable* Instantiate(BMessage* archive);
BCursor& operator=(const BCursor& other);
bool operator==(const BCursor& other) const;
bool operator!=(const BCursor& other) const;
private: private:
virtual status_t Perform(perform_code d, void* arg); virtual status_t Perform(perform_code d, void* arg);
@@ -27,6 +33,8 @@ class BCursor : BArchivable {
virtual void _ReservedCursor3(); virtual void _ReservedCursor3();
virtual void _ReservedCursor4(); virtual void _ReservedCursor4();
void _FreeCursorData();
private: private:
friend class BApplication; friend class BApplication;
friend class BView; friend class BView;
+1
View File
@@ -68,6 +68,7 @@ enum {
AS_QUERY_CURSOR_HIDDEN, AS_QUERY_CURSOR_HIDDEN,
AS_CREATE_CURSOR, AS_CREATE_CURSOR,
AS_REFERENCE_CURSOR,
AS_DELETE_CURSOR, AS_DELETE_CURSOR,
AS_BEGIN_RECT_TRACKING, AS_BEGIN_RECT_TRACKING,
+62 -8
View File
@@ -63,6 +63,16 @@ BCursor::BCursor(const void *cursorData)
} }
BCursor::BCursor(const BCursor& other)
:
fServerToken(-1),
fNeedToFree(false),
fPendingViewCursor(false)
{
*this = other;
}
BCursor::BCursor(BMessage *data) BCursor::BCursor(BMessage *data)
{ {
// undefined on BeOS // undefined on BeOS
@@ -74,14 +84,7 @@ BCursor::BCursor(BMessage *data)
BCursor::~BCursor() BCursor::~BCursor()
{ {
// Notify server to deallocate server-side objects for this cursor _FreeCursorData();
if (fNeedToFree) {
BPrivate::AppServerLink link;
link.StartMessage(AS_DELETE_CURSOR);
link.Attach<int32>(fServerToken);
link.Attach<bool>(fPendingViewCursor);
link.Flush();
}
} }
@@ -101,6 +104,42 @@ BCursor::Instantiate(BMessage *data)
} }
BCursor&
BCursor::operator=(const BCursor& other)
{
if (&other != this && other != *this) {
_FreeCursorData();
fServerToken = other.fServerToken;
fNeedToFree = other.fNeedToFree;
fPendingViewCursor = false;
if (fNeedToFree) {
// Tell app_server that there is another reference for this
// cursor data!
BPrivate::AppServerLink link;
link.StartMessage(AS_REFERENCE_CURSOR);
link.Attach<int32>(fServerToken);
}
}
return *this;
}
bool
BCursor::operator==(const BCursor& other) const
{
return fServerToken == other.fServerToken;
}
bool
BCursor::operator!=(const BCursor& other) const
{
return fServerToken != other.fServerToken;
}
status_t status_t
BCursor::Perform(perform_code d, void *arg) BCursor::Perform(perform_code d, void *arg)
{ {
@@ -112,3 +151,18 @@ void BCursor::_ReservedCursor1() {}
void BCursor::_ReservedCursor2() {} void BCursor::_ReservedCursor2() {}
void BCursor::_ReservedCursor3() {} void BCursor::_ReservedCursor3() {}
void BCursor::_ReservedCursor4() {} void BCursor::_ReservedCursor4() {}
void
BCursor::_FreeCursorData()
{
// Notify server to deallocate server-side objects for this cursor
if (fNeedToFree) {
BPrivate::AppServerLink link;
link.StartMessage(AS_DELETE_CURSOR);
link.Attach<int32>(fServerToken);
link.Attach<bool>(fPendingViewCursor);
link.Flush();
}
}
+24 -2
View File
@@ -954,6 +954,27 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
fLink.Flush(); fLink.Flush();
break; break;
} }
case AS_REFERENCE_CURSOR:
{
STRACE(("ServerApp %s: Reference BCursor\n", Signature()));
// Attached data:
// 1) int32 token ID of the cursor to reference
int32 token;
if (link.Read<int32>(&token) != B_OK)
break;
if (!fDesktop->GetCursorManager().Lock())
break;
ServerCursor* cursor
= fDesktop->GetCursorManager().FindCursor(token);
if (cursor != NULL)
cursor->Acquire();
fDesktop->GetCursorManager().Unlock();
break;
}
case AS_DELETE_CURSOR: case AS_DELETE_CURSOR:
{ {
STRACE(("ServerApp %s: Delete BCursor\n", Signature())); STRACE(("ServerApp %s: Delete BCursor\n", Signature()));
@@ -968,8 +989,9 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
if (!fDesktop->GetCursorManager().Lock()) if (!fDesktop->GetCursorManager().Lock())
break; break;
ServerCursor* cursor = fDesktop->GetCursorManager().FindCursor(token); ServerCursor* cursor
if (cursor) { = fDesktop->GetCursorManager().FindCursor(token);
if (cursor != NULL) {
if (pendingViewCursor) if (pendingViewCursor)
cursor->SetPendingViewCursor(true); cursor->SetPendingViewCursor(true);