* Got rid of unused BLooper members
* renamed fTaskID to fThread
* Removed private and deprecated AddLooper()/RemoveLooper()/... stuff; BLooper is now
  directly calling BLooperList methods.
* Got rid of extensive and useless comments
* Made a few TODOs more clear
* Merged InitData() and InitData(...) to _InitData(...)
* BLooper::Team() now uses BPrivate::current_team(), sTeamID is gone now.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@19966 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2007-01-26 12:42:18 +00:00
parent aa33d0a928
commit c01f349e6d
4 changed files with 113 additions and 312 deletions
+10 -30
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright 2001-2006, Haiku Inc. All Rights Reserved. * Copyright 2001-2007, Haiku Inc. All Rights Reserved.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
* *
* Authors: * Authors:
@@ -41,9 +41,9 @@ public:
status_t PostMessage(uint32 command); status_t PostMessage(uint32 command);
status_t PostMessage(BMessage* message); status_t PostMessage(BMessage* message);
status_t PostMessage(uint32 command, BHandler* handler, status_t PostMessage(uint32 command, BHandler* handler,
BHandler* reply_to = NULL); BHandler* replyTo = NULL);
status_t PostMessage(BMessage* message, BHandler* handler, status_t PostMessage(BMessage* message, BHandler* handler,
BHandler* reply_to = NULL); BHandler* replyTo = NULL);
virtual void DispatchMessage(BMessage* message, BHandler* handler); virtual void DispatchMessage(BMessage* message, BHandler* handler);
virtual void MessageReceived(BMessage* msg); virtual void MessageReceived(BMessage* msg);
@@ -72,7 +72,7 @@ public:
status_t LockWithTimeout(bigtime_t timeout); status_t LockWithTimeout(bigtime_t timeout);
thread_id Thread() const; thread_id Thread() const;
team_id Team() const; team_id Team() const;
static BLooper* LooperForThread(thread_id tid); static BLooper* LooperForThread(thread_id thread);
// Loop debugging // Loop debugging
thread_id LockingThread() const; thread_id LockingThread() const;
@@ -92,7 +92,7 @@ public:
virtual void SetCommonFilterList(BList* filters); virtual void SetCommonFilterList(BList* filters);
BList* CommonFilterList() const; BList* CommonFilterList() const;
// Private or reserved --------------------------------------------------------- // Private or reserved
virtual status_t Perform(perform_code d, void* arg); virtual status_t Perform(perform_code d, void* arg);
protected: protected:
@@ -108,8 +108,6 @@ private:
friend class BHandler; friend class BHandler;
friend class BPrivate::BLooperList; friend class BPrivate::BLooperList;
friend port_id _get_looper_port_(const BLooper* ); friend port_id _get_looper_port_(const BLooper* );
friend status_t _safe_get_server_token_(const BLooper* , int32* );
friend team_id _find_cur_team_id_();
virtual void _ReservedLooper1(); virtual void _ReservedLooper1();
virtual void _ReservedLooper2(); virtual void _ReservedLooper2();
@@ -132,8 +130,7 @@ private:
static status_t _LockComplete(BLooper* loop, int32 old, static status_t _LockComplete(BLooper* loop, int32 old,
thread_id this_tid, sem_id sem, thread_id this_tid, sem_id sem,
bigtime_t timeout); bigtime_t timeout);
void InitData(); void _InitData(const char* name, int32 priority, int32 capacity);
void InitData(const char* name, int32 prio, int32 capacity);
void AddMessage(BMessage* msg); void AddMessage(BMessage* msg);
void _AddMessagePriv(BMessage* msg); void _AddMessagePriv(BMessage* msg);
static status_t _task0_(void* arg); static status_t _task0_(void* arg);
@@ -153,38 +150,21 @@ private:
BHandler* resolve_specifier(BHandler* target, BMessage* msg); BHandler* resolve_specifier(BHandler* target, BMessage* msg);
void UnlockFully(); void UnlockFully();
static uint32 sLooperID;
static team_id sTeamID;
// DEPRECATED
static void AddLooper(BLooper* l);
static bool IsLooperValid(const BLooper* l);
static void RemoveLooper(BLooper* l);
static void GetLooperList(BList* list);
static BLooper* LooperForName(const char* name);
static BLooper* LooperForPort(port_id port);
uint32 fLooperID;
BMessageQueue* fQueue; BMessageQueue* fQueue;
BMessage* fLastMessage; BMessage* fLastMessage;
port_id fMsgPort; port_id fMsgPort;
long fAtomicCount; int32 fAtomicCount;
sem_id fLockSem; sem_id fLockSem;
long fOwnerCount; int32 fOwnerCount;
thread_id fOwner; thread_id fOwner;
thread_id fTaskID; thread_id fThread;
uint32 _unused1;
int32 fInitPriority; int32 fInitPriority;
BHandler* fPreferred; BHandler* fPreferred;
BList fHandlers; BList fHandlers;
BList* fCommonFilters; BList* fCommonFilters;
bool fTerminating; bool fTerminating;
bool fRunCalled; bool fRunCalled;
thread_id fCachedPid; uint32 _reserved[12];
size_t fCachedStack;
void* fMsgBuffer;
size_t fMsgBufferSize;
uint32 _reserved[6];
}; };
#endif // _LOOPER_H #endif // _LOOPER_H
+5 -8
View File
@@ -1,10 +1,11 @@
/* /*
* Copyright 2001-2006, Haiku. * Copyright 2001-2007, Haiku.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
* *
* Authors: * Authors:
* Erik Jaesler ([email protected]) * Erik Jaesler ([email protected])
* Jerome Duval * Jerome Duval
* Axel Dörfler, [email protected]
*/ */
@@ -483,17 +484,13 @@ BApplication::Run()
if (fRunCalled) if (fRunCalled)
debugger("BApplication::Run was already called. Can only be called once."); debugger("BApplication::Run was already called. Can only be called once.");
// Note: We need a local variable too (for the return value), since fThread = find_thread(NULL);
// fTaskID is cleared by Quit().
// ToDo: actually, it's not clobbered there?!
thread_id thread = fTaskID = find_thread(NULL);
fRunCalled = true; fRunCalled = true;
task_looper(); task_looper();
delete fPulseRunner; delete fPulseRunner;
return thread; return fThread;
} }
@@ -514,7 +511,7 @@ BApplication::Quit()
// Delete the object, if not running only. // Delete the object, if not running only.
if (!fRunCalled) { if (!fRunCalled) {
delete this; delete this;
} else if (find_thread(NULL) != fTaskID) { } else if (find_thread(NULL) != fThread) {
// ToDo: why shouldn't we set fTerminating to true directly in this case? // ToDo: why shouldn't we set fTerminating to true directly in this case?
// We are not the looper thread. // We are not the looper thread.
// We push a _QUIT_ into the queue. // We push a _QUIT_ into the queue.
+89 -256
View File
@@ -11,13 +11,23 @@
/*! BLooper class spawns a thread that runs a message loop. */ /*! BLooper class spawns a thread that runs a message loop. */
/** #include <AppMisc.h>
@note Although I'm implementing "by the book" for now, I would like to #include <LooperList.h>
refactor sLooperList and all of the functions that operate on it #include <MessagePrivate.h>
into their own class in the BPrivate namespace. #include <ObjectLocker.h>
#include <TokenSpace.h>
#include <Autolock.h>
#include <Looper.h>
#include <Message.h>
#include <MessageFilter.h>
#include <MessageQueue.h>
#include <Messenger.h>
#include <PropertyInfo.h>
#include <new>
#include <stdio.h>
Also considering adding the thread priority when archiving.
*/
// debugging // debugging
//#define DBG(x) x //#define DBG(x) x
@@ -35,21 +45,6 @@ static BLocker sDebugPrintLocker("BLooper debug print");
}) })
*/ */
#include <stdio.h>
#include <Autolock.h>
#include <Looper.h>
#include <Message.h>
#include <MessageFilter.h>
#include <MessageQueue.h>
#include <Messenger.h>
#include <PropertyInfo.h>
#include <LooperList.h>
#include <MessagePrivate.h>
#include <ObjectLocker.h>
#include <TokenSpace.h>
#define FILTER_LIST_BLOCK_SIZE 5 #define FILTER_LIST_BLOCK_SIZE 5
#define DATA_BLOCK_SIZE 5 #define DATA_BLOCK_SIZE 5
@@ -62,9 +57,6 @@ using BPrivate::BLooperList;
port_id _get_looper_port_(const BLooper* looper); port_id _get_looper_port_(const BLooper* looper);
uint32 BLooper::sLooperID = (uint32)B_ERROR;
team_id BLooper::sTeamID = (team_id)B_ERROR;
enum { enum {
BLOOPER_PROCESS_INTERNALLY = 0, BLOOPER_PROCESS_INTERNALLY = 0,
BLOOPER_HANDLER_BY_INDEX BLOOPER_HANDLER_BY_INDEX
@@ -113,7 +105,7 @@ struct _loop_data_ {
BLooper::BLooper(const char* name, int32 priority, int32 port_capacity) BLooper::BLooper(const char* name, int32 priority, int32 port_capacity)
: BHandler(name) : BHandler(name)
{ {
InitData(name, priority, port_capacity); _InitData(name, priority, port_capacity);
} }
@@ -136,11 +128,12 @@ BLooper::~BLooper()
if (fMsgPort >= 0) if (fMsgPort >= 0)
close_port(fMsgPort); close_port(fMsgPort);
BMessage *msg;
// Clear the queue so our call to IsMessageWaiting() below doesn't give // Clear the queue so our call to IsMessageWaiting() below doesn't give
// us bogus info // us bogus info
while ((msg = fQueue->NextMessage()) != NULL) { BMessage *message;
delete msg; // msg will automagically post generic reply while ((message = fQueue->NextMessage()) != NULL) {
delete message;
// msg will automagically post generic reply
} }
do { do {
@@ -166,7 +159,7 @@ BLooper::~BLooper()
} }
Unlock(); Unlock();
RemoveLooper(this); gLooperList.RemoveLooper(this);
delete_sem(fLockSem); delete_sem(fLockSem);
} }
@@ -179,7 +172,7 @@ BLooper::BLooper(BMessage *data)
|| portCapacity < 0) || portCapacity < 0)
portCapacity = B_LOOPER_PORT_DEFAULT_CAPACITY; portCapacity = B_LOOPER_PORT_DEFAULT_CAPACITY;
InitData(Name(), B_NORMAL_PRIORITY, portCapacity); _InitData(Name(), B_NORMAL_PRIORITY, portCapacity);
} }
@@ -205,6 +198,8 @@ BLooper::Archive(BMessage *data, bool deep) const
if (status == B_OK) if (status == B_OK)
status = data->AddInt32("_port_cap", info.capacity); status = data->AddInt32("_port_cap", info.capacity);
// TODO: what about the thread priority?
return status; return status;
} }
@@ -245,18 +240,7 @@ void
BLooper::DispatchMessage(BMessage *message, BHandler *handler) BLooper::DispatchMessage(BMessage *message, BHandler *handler)
{ {
PRINT(("BLooper::DispatchMessage(%.4s)\n", (char*)&message->what)); PRINT(("BLooper::DispatchMessage(%.4s)\n", (char*)&message->what));
/** @note
Initially, DispatchMessage() was locking the looper, calling the
filtering API, determining whether to use fPreferred or not, and
deleting the message. A look at the BeBook, however, reveals that
all this function does is handle its own B_QUIT_REQUESTED messages
and pass everything else to handler->MessageReceived(). Clearly the
rest must be happening in task_looper(). This makes a lot of sense
because otherwise every derived class would have to figure out when
to use fPreferred, handle the locking and filtering and delete the
message. Even if the BeBook didn't say as much, it would make total
sense to hoist that functionality out of here and into task_looper().
*/
switch (message->what) { switch (message->what) {
case _QUIT_: case _QUIT_:
// Can't call Quit() to do this, because of the slight chance // Can't call Quit() to do this, because of the slight chance
@@ -286,10 +270,7 @@ BLooper::DispatchMessage(BMessage *message, BHandler *handler)
void void
BLooper::MessageReceived(BMessage *msg) BLooper::MessageReceived(BMessage *msg)
{ {
// TODO: verify // TODO: implement scripting support
// The BeBook says this "simply calls the inherited function. ...the BLooper
// implementation does nothing of importance." Which is not the same as
// saying it does nothing. Investigate.
BHandler::MessageReceived(msg); BHandler::MessageReceived(msg);
} }
@@ -325,17 +306,6 @@ BLooper::IsMessageWaiting() const
if (!fQueue->IsEmpty()) if (!fQueue->IsEmpty())
return true; return true;
/**
@note: What we're doing here differs slightly from the R5 implementation.
It appears that they probably return count != 0, which gives an
incorrect true result when port_buffer_size_etc() would block --
which indicates that the port's buffer is empty, so we should return
false. Since we don't actually care about what the error is, we
just return count > 0. This has some interesting consequences in
that we will correctly return 'false' if the port is empty
(B_WOULD_BLOCK), whereas R5 will return true. We call that a bug
where I come from. ;)
*/
int32 count; int32 count;
do { do {
count = port_buffer_size_etc(fMsgPort, B_RELATIVE_TIMEOUT, 0); count = port_buffer_size_etc(fMsgPort, B_RELATIVE_TIMEOUT, 0);
@@ -436,12 +406,12 @@ BLooper::Run()
if (fRunCalled) { if (fRunCalled) {
// Not allowed to call Run() more than once // Not allowed to call Run() more than once
debugger("can't call BLooper::Run twice!"); debugger("can't call BLooper::Run twice!");
return fTaskID; return fThread;
} }
fTaskID = spawn_thread(_task0_, Name(), fInitPriority, this); fThread = spawn_thread(_task0_, Name(), fInitPriority, this);
if (fTaskID < B_OK) if (fThread < B_OK)
return fTaskID; return fThread;
if (fMsgPort < B_OK) if (fMsgPort < B_OK)
return fMsgPort; return fMsgPort;
@@ -449,11 +419,11 @@ BLooper::Run()
fRunCalled = true; fRunCalled = true;
Unlock(); Unlock();
status_t err = resume_thread(fTaskID); status_t err = resume_thread(fThread);
if (err < B_OK) if (err < B_OK)
return err; return err;
return fTaskID; return fThread;
} }
@@ -479,7 +449,7 @@ BLooper::Quit()
PRINT((" Run() has not been called yet\n")); PRINT((" Run() has not been called yet\n"));
fTerminating = true; fTerminating = true;
delete this; delete this;
} else if (find_thread(NULL) == fTaskID) { } else if (find_thread(NULL) == fThread) {
PRINT((" We are the looper thread\n")); PRINT((" We are the looper thread\n"));
fTerminating = true; fTerminating = true;
delete this; delete this;
@@ -569,16 +539,7 @@ PRINT(("BLooper::Unlock() done\n"));
bool bool
BLooper::IsLocked() const BLooper::IsLocked() const
{ {
// We have to lock the list for the call to IsLooperValid(). Has the side if (!gLooperList.IsLooperValid(this)) {
// effect of not letting the looper get deleted while we're here.
BObjectLocker<BLooperList> ListLock(gLooperList);
if (!ListLock.IsLocked()) {
// If we can't lock the list, our semaphore is probably toast
return false;
}
if (!IsLooperValid(this)) {
// The looper is gone, so of course it's not locked // The looper is gone, so of course it's not locked
return false; return false;
} }
@@ -598,25 +559,21 @@ BLooper::LockWithTimeout(bigtime_t timeout)
thread_id thread_id
BLooper::Thread() const BLooper::Thread() const
{ {
return fTaskID; return fThread;
} }
team_id team_id
BLooper::Team() const BLooper::Team() const
{ {
return sTeamID; return BPrivate::current_team();
} }
BLooper* BLooper*
BLooper::LooperForThread(thread_id tid) BLooper::LooperForThread(thread_id thread)
{ {
BObjectLocker<BLooperList> ListLock(gLooperList); return gLooperList.LooperForThread(thread);
if (ListLock.IsLocked())
return gLooperList.LooperForThread(tid);
return NULL;
} }
@@ -856,7 +813,7 @@ BLooper::BLooper(int32 priority, port_id port, const char* name)
{ {
// This must be a legacy constructor // This must be a legacy constructor
fMsgPort = port; fMsgPort = port;
InitData(name, priority, B_LOOPER_PORT_DEFAULT_CAPACITY); _InitData(name, priority, B_LOOPER_PORT_DEFAULT_CAPACITY);
} }
@@ -868,7 +825,7 @@ BLooper::_PostMessage(BMessage *msg, BHandler *handler,
if (!listLocker.IsLocked()) if (!listLocker.IsLocked())
return B_ERROR; return B_ERROR;
if (!IsLooperValid(this)) if (!gLooperList.IsLooperValid(this))
return B_BAD_VALUE; return B_BAD_VALUE;
// Does handler belong to this looper? // Does handler belong to this looper?
@@ -884,120 +841,66 @@ BLooper::_PostMessage(BMessage *msg, BHandler *handler,
} }
status_t /*!
BLooper::_Lock(BLooper* loop, port_id port, bigtime_t timeout) Locks a looper either by port or using a direct pointer to the looper.
{
PRINT(("BLooper::_Lock(%p, %lx)\n", loop, port));
/**
@note The assumption I'm under here is that since we can get the port of
the BLooper directly from the BLooper itself, the port parameter is
for identifying BLoopers by port_id when a pointer to the BLooper in
question is not available. So this function has two modes:
o When loop != NULL, use it directly
o When loop == NULL and port is valid, use the port_id to get
the looper
I scoured the docs to find out what constitutes a valid port_id to
no avail. Since create_port uses the standard error values in its
returned port_id, I'll assume that anything less than zero is a safe
bet as an *invalid* port_id. I'm guessing that, like thread and
semaphore ids, anything >= zero is valid. So, the short version of
this reads: if you don't want to find by port_id, make port = -1.
Another assumption I'm making is that Lock() and LockWithTimeout() \param looper looper to lock, if not NULL
are covers for this function. If it turns out that we don't really \param port port to identify the looper in case \a looper is NULL
need this function, I may refactor this code into LockWithTimeout() \param timeout timeout for acquiring the lock
and have Lock() call it instead. This function could then be */
removed. status_t
*/ BLooper::_Lock(BLooper* looper, port_id port, bigtime_t timeout)
{
PRINT(("BLooper::_Lock(%p, %lx)\n", looper, port));
// Check params (loop, port) // Check params (loop, port)
if (!loop && port < 0) if (looper == NULL && port < 0) {
{ PRINT(("BLooper::_Lock() done 1\n"));
PRINT(("BLooper::_Lock() done 1\n"));
return B_BAD_VALUE; return B_BAD_VALUE;
} }
// forward declared so I can use BAutolock on sLooperListLock thread_id currentThread = find_thread(NULL);
thread_id curThread; int32 oldCount;
sem_id sem; sem_id sem;
/**
@note We lock the looper list at the start of the lock operation to
prevent the looper getting removed from the list while we're
doing list operations. Also ensures that the looper doesn't
get deleted here (since ~BLooper() has to lock the list as
well to remove itself).
*/
int32 oldCount;
{ {
BObjectLocker<BLooperList> ListLock(gLooperList); BObjectLocker<BLooperList> ListLock(gLooperList);
if (!ListLock.IsLocked()) if (!ListLock.IsLocked())
{ return B_BAD_VALUE;
// If we can't lock, the semaphore is probably
// gone, which leaves us in no-man's land // Look up looper by port_id, if necessary
PRINT(("BLooper::_Lock() done 2\n")); if (looper == NULL) {
looper = gLooperList.LooperForPort(port);
if (looper == NULL) {
PRINT(("BLooper::_Lock() done 3\n"));
return B_BAD_VALUE;
}
} else if (!gLooperList.IsLooperValid(looper)) {
// Check looper validity
PRINT(("BLooper::_Lock() done 4\n"));
return B_BAD_VALUE; return B_BAD_VALUE;
} }
// Look up looper by port_id, if necessary // Check for nested lock attempt
if (!loop) if (currentThread == looper->fOwner) {
{ ++looper->fOwnerCount;
loop = LooperForPort(port); PRINT(("BLooper::_Lock() done 5: fOwnerCount: %ld\n", loop->fOwnerCount));
if (!loop)
{
PRINT(("BLooper::_Lock() done 3\n"));
return B_BAD_VALUE;
}
}
else
{
// Check looper validity
if (!IsLooperValid(loop))
{
PRINT(("BLooper::_Lock() done 4\n"));
return B_BAD_VALUE;
}
}
// Is the looper trying to lock itself?
// Check for nested lock attempt
curThread = find_thread(NULL);
if (curThread == loop->fOwner)
{
// Bump fOwnerCount
++loop->fOwnerCount;
PRINT(("BLooper::_Lock() done 5: fOwnerCount: %ld\n", loop->fOwnerCount));
return B_OK; return B_OK;
} }
// Something external to the looper is attempting to lock // Cache the semaphore, so that we can safely access it after having
// Cache the semaphore // unlocked the looper list
sem = loop->fLockSem; sem = looper->fLockSem;
if (sem < 0) {
// Validate the semaphore PRINT(("BLooper::_Lock() done 6\n"));
if (sem < 0)
{
PRINT(("BLooper::_Lock() done 6\n"));
return B_BAD_VALUE; return B_BAD_VALUE;
} }
// Bump the requested lock count (using fAtomicCount for this)
oldCount = atomic_add(&loop->fAtomicCount, 1);
// sLooperListLock automatically released here // Bump the requested lock count (using fAtomicCount for this)
oldCount = atomic_add(&looper->fAtomicCount, 1);
} }
/** return _LockComplete(looper, oldCount, currentThread, sem, timeout);
@note We have to operate with the looper list unlocked during semaphore
acquisition so that the rest of the application doesn't have to
wait for this lock to happen. This is why we cached fLockSem
earlier -- with the list unlocked, the looper might get deleted
right out from under us. This is also why we use a raw semaphore
instead of the easier-to-deal-with BLocker; you can't cache a
BLocker.
*/
// acquire the lock for real
return _LockComplete(loop, oldCount, curThread, sem, timeout);
} }
@@ -1009,25 +912,24 @@ BLooper::_LockComplete(BLooper *looper, int32 oldCount, thread_id thread, sem_id
#if DEBUG < 1 #if DEBUG < 1
if (oldCount > 0) { if (oldCount > 0) {
#endif #endif
do { do {
err = acquire_sem_etc(sem, 1, B_RELATIVE_TIMEOUT, timeout); err = acquire_sem_etc(sem, 1, B_RELATIVE_TIMEOUT, timeout);
} while (err == B_INTERRUPTED); } while (err == B_INTERRUPTED);
#if DEBUG < 1 #if DEBUG < 1
} }
#endif #endif
if (err == B_OK) { if (err == B_OK) {
// Assign current thread to fOwner
looper->fOwner = thread; looper->fOwner = thread;
// Reset fOwnerCount to 1
looper->fOwnerCount = 1; looper->fOwnerCount = 1;
} }
PRINT(("BLooper::_LockComplete() done: %lx\n", err));
PRINT(("BLooper::_LockComplete() done: %lx\n", err));
return err; return err;
} }
void void
BLooper::InitData() BLooper::_InitData(const char *name, int32 priority, int32 portCapacity)
{ {
fOwner = B_ERROR; fOwner = B_ERROR;
fRunCalled = false; fRunCalled = false;
@@ -1035,24 +937,11 @@ BLooper::InitData()
fCommonFilters = NULL; fCommonFilters = NULL;
fLastMessage = NULL; fLastMessage = NULL;
fPreferred = NULL; fPreferred = NULL;
fTaskID = B_ERROR; fThread = B_ERROR;
fTerminating = false; fTerminating = false;
fMsgPort = -1; fMsgPort = -1;
fAtomicCount = 0; fAtomicCount = 0;
if (sTeamID == -1) {
thread_info info;
get_thread_info(find_thread(NULL), &info);
sTeamID = info.team;
}
}
void
BLooper::InitData(const char *name, int32 priority, int32 portCapacity)
{
InitData();
if (name == NULL) if (name == NULL)
name = "anonymous looper"; name = "anonymous looper";
@@ -1069,8 +958,7 @@ BLooper::InitData(const char *name, int32 priority, int32 portCapacity)
fInitPriority = priority; fInitPriority = priority;
BObjectLocker<BLooperList> ListLock(gLooperList); gLooperList.AddLooper(this);
AddLooper(this);
AddHandler(this); AddHandler(this);
} }
@@ -1325,7 +1213,7 @@ BLooper::_QuitRequested(BMessage *msg)
|| (msg->FindBool("_shutdown_", &shutdown) == B_OK && shutdown)) { || (msg->FindBool("_shutdown_", &shutdown) == B_OK && shutdown)) {
BMessage replyMsg(B_REPLY); BMessage replyMsg(B_REPLY);
replyMsg.AddBool("result", isQuitting); replyMsg.AddBool("result", isQuitting);
replyMsg.AddInt32("thread", fTaskID); replyMsg.AddInt32("thread", fThread);
msg->SendReply(&replyMsg); msg->SendReply(&replyMsg);
} }
@@ -1515,61 +1403,6 @@ BLooper::UnlockFully()
} }
void
BLooper::AddLooper(BLooper *looper)
{
if (gLooperList.IsLocked())
gLooperList.AddLooper(looper);
}
bool
BLooper::IsLooperValid(const BLooper *looper)
{
if (gLooperList.IsLocked())
return gLooperList.IsLooperValid(looper);
return false;
}
void
BLooper::RemoveLooper(BLooper *looper)
{
if (gLooperList.IsLocked())
gLooperList.RemoveLooper(looper);
}
void
BLooper::GetLooperList(BList* list)
{
BObjectLocker<BLooperList> ListLock(gLooperList);
if (ListLock.IsLocked())
gLooperList.GetLooperList(list);
}
BLooper *
BLooper::LooperForName(const char* name)
{
if (gLooperList.IsLocked())
return gLooperList.LooperForName(name);
return NULL;
}
BLooper *
BLooper::LooperForPort(port_id port)
{
if (gLooperList.IsLocked())
return gLooperList.LooperForPort(port);
return NULL;
}
// #pragma mark - // #pragma mark -
+9 -18
View File
@@ -1066,7 +1066,7 @@ FrameMoved(origin);
case _UPDATE_: case _UPDATE_:
{ {
//bigtime_t now = system_time(); //bigtime_t now = system_time();
STRACE(("info:BWindow handling _UPDATE_.\n")); STRACE(("info:BWindow handling _UPDATE_.\n"));
BRect updateRect; BRect updateRect;
@@ -1088,14 +1088,14 @@ FrameMoved(origin);
if (origin != fFrame.LeftTop()) { if (origin != fFrame.LeftTop()) {
// TODO: remove code duplicatation with // TODO: remove code duplicatation with
// B_WINDOW_MOVED case... // B_WINDOW_MOVED case...
//printf("window position was not up to date\n"); //printf("window position was not up to date\n");
fFrame.OffsetTo(origin); fFrame.OffsetTo(origin);
FrameMoved(origin); FrameMoved(origin);
} }
if (width != fFrame.Width() || height != fFrame.Height()) { if (width != fFrame.Width() || height != fFrame.Height()) {
// TODO: remove code duplicatation with // TODO: remove code duplicatation with
// B_WINDOW_RESIZED case... // B_WINDOW_RESIZED case...
//printf("window size was not up to date\n"); //printf("window size was not up to date\n");
fFrame.right = fFrame.left + width; fFrame.right = fFrame.left + width;
fFrame.bottom = fFrame.top + height; fFrame.bottom = fFrame.top + height;
@@ -1136,7 +1136,7 @@ FrameMoved(origin);
fLink->Flush(); fLink->Flush();
fInTransaction = false; fInTransaction = false;
//printf("BWindow(%s) - UPDATE took %lld usecs\n", Title(), system_time() - now); //printf("BWindow(%s) - UPDATE took %lld usecs\n", Title(), system_time() - now);
break; break;
} }
@@ -2194,7 +2194,7 @@ BWindow::Show()
if (fLink->SenderPort() < B_OK) { if (fLink->SenderPort() < B_OK) {
// We don't have valid app_server connection; there is no point // We don't have valid app_server connection; there is no point
// in starting our looper // in starting our looper
fTaskID = B_ERROR; fThread = B_ERROR;
return; return;
} else } else
Run(); Run();
@@ -2517,18 +2517,11 @@ BWindow::task_looper()
if (IsLocked()) if (IsLocked())
debugger("window must not be locked!"); debugger("window must not be locked!");
// loop: As long as we are not terminating.
while (!fTerminating) { while (!fTerminating) {
// TODO: timeout determination algo
// Read from message port (how do we determine what the timeout is?)
BMessage* msg = MessageFromPort();
// Did we get a message? // Did we get a message?
if (msg) { BMessage* msg = MessageFromPort();
// Add to queue if (msg)
fQueue->AddMessage(msg); _AddMessagePriv(msg);
} else
continue;
// Get message count from port // Get message count from port
int32 msgCount = port_count(fMsgPort); int32 msgCount = port_count(fMsgPort);
@@ -2538,11 +2531,9 @@ BWindow::task_looper()
msg = MessageFromPort(0); msg = MessageFromPort(0);
// Add messages to queue // Add messages to queue
if (msg) if (msg)
fQueue->AddMessage(msg); _AddMessagePriv(msg);
} }
// loop: As long as there are messages in the queue and the port is
// empty... and we are not terminating, of course.
bool dispatchNextMessage = true; bool dispatchNextMessage = true;
while (!fTerminating && dispatchNextMessage) { while (!fTerminating && dispatchNextMessage) {
// Get next message from queue (assign to fLastMessage) // Get next message from queue (assign to fLastMessage)