Fixing timers on BeOS and making a component out of them.
Thanks to Yannick Koehler <ykoehler@mythrium.com> for the patch and for having patience while we hashed out the fix for the fix. Bug #55674. r=cls@seawood.org sr=scc@mozilla.org git-svn-id: svn://10.0.0.236/trunk@83780 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
parent
ce09d96e2e
commit
1a8a90b822
@ -59,7 +59,6 @@ CPPSRCS = \
|
||||
SHARED_LIBRARY_LIBS = $(DIST)/lib/libxpwidgets_s.a
|
||||
|
||||
EXTRA_DSO_LDOPTS = \
|
||||
-ltimer_beos \
|
||||
$(TOOLKIT_DSO_LDOPTS) \
|
||||
$(MOZ_COMPONENT_LIBS) \
|
||||
-lgkgfx \
|
||||
@ -72,3 +71,8 @@ DEFINES += -D_IMPL_NS_WIDGET -I$(srcdir)/../xpwidgets -I$(srcdir)
|
||||
|
||||
CXXFLAGS += $(TK_CFLAGS)
|
||||
|
||||
INCLUDES += \
|
||||
-I$(srcdir)/../xpwidgets \
|
||||
-I$(srcdir) \
|
||||
-I$(srcdir)/../../timer/src/beos \
|
||||
$(NULL)
|
||||
|
||||
@ -27,6 +27,7 @@
|
||||
#include "nsIAppShell.h"
|
||||
#include "nsWindow.h"
|
||||
#include "nsSwitchToUIThread.h"
|
||||
#include "nsTimerBeOS.h"
|
||||
#include "plevent.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
@ -185,8 +186,11 @@ nsresult nsAppShell::Run()
|
||||
switch(code)
|
||||
{
|
||||
case 'WMti' :
|
||||
extern void nsTimerExpired(void *); // hack: this is in gfx
|
||||
nsTimerExpired(id.data);
|
||||
{
|
||||
// Hack
|
||||
nsCOMPtr<nsTimerBeOS> timer = (nsTimerBeOS *)id.data;
|
||||
timer->FireTimeout();
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_CALLMETHOD :
|
||||
|
||||
@ -24,7 +24,7 @@
|
||||
#include "nsWindow.h"
|
||||
#include "prmon.h"
|
||||
#include "prtime.h"
|
||||
#include "nsITimer.h"
|
||||
#include "nsTimerBeOS.h"
|
||||
#include "nsGUIEvent.h"
|
||||
#include "nsSwitchToUIThread.h"
|
||||
#include "plevent.h"
|
||||
@ -107,8 +107,11 @@ void nsToolkit::RunPump(void* arg)
|
||||
switch(code)
|
||||
{
|
||||
case 'WMti' :
|
||||
extern void nsTimerExpired(void *); // hack: this is in gfx
|
||||
nsTimerExpired(id.data);
|
||||
{
|
||||
// Hack
|
||||
nsCOMPtr<nsTimerBeOS> timer = (nsTimerBeOS *)id.data;
|
||||
timer->FireTimeout();
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_CALLMETHOD :
|
||||
|
||||
@ -26,20 +26,22 @@ VPATH = @srcdir@
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
MODULE = timer
|
||||
LIBRARY_NAME = timer_beos
|
||||
LIBRARY_NAME = timer_$(TIMER_SUFFIX)
|
||||
|
||||
|
||||
CPPSRCS = nsTimer.cpp
|
||||
CPPSRCS = nsTimerBeOS.cpp
|
||||
|
||||
TIMER_SUFFIX = beos
|
||||
IS_COMPONENT = 1
|
||||
CPPSRCS += nsTimerBeOSFactory.cpp
|
||||
EXTRA_DSO_LDOPTS = $(MOZ_TK_LDFLAGS) $(MOZ_COMPONENT_LIBS)
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
DEFINES += -D_IMPL_NS_TIMER
|
||||
CXXFLAGS += $(TK_CFLAGS)
|
||||
INCLUDES += $(TK_CFLAGS) -I$(srcdir)/..
|
||||
INCLUDES += $(MOZ_TK_CFLAGS) -I$(srcdir)/..
|
||||
|
||||
EXTRA_DSO_LDOPTS += \
|
||||
$(XPCOM_LIBS) \
|
||||
$(TK_LIBS) \
|
||||
$(NSPR_LIBS)
|
||||
# Since we are changing the library to a component,
|
||||
# make sure that the old copy in $(DIST) does not exist
|
||||
export::
|
||||
$(RM) -f $(DIST)/bin/libtimer_$(TIMER_SUFFIX).so $(DIST)/lib/libtimer_$(TIMER_SUFFIX).so $(DIST)/bin/libtimer_$(TIMER_SUFFIX).so.stub
|
||||
|
||||
|
||||
298
mozilla/widget/timer/src/beos/nsTimerBeOS.cpp
Normal file
298
mozilla/widget/timer/src/beos/nsTimerBeOS.cpp
Normal file
@ -0,0 +1,298 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
|
||||
#include "nsVoidArray.h"
|
||||
#include "nsTimerBeOS.h"
|
||||
#include "nsCOMPtr.h"
|
||||
|
||||
#include <Application.h>
|
||||
#include <Message.h>
|
||||
#include <signal.h>
|
||||
|
||||
static NS_DEFINE_IID(kITimerIID, NS_ITIMER_IID);
|
||||
|
||||
struct ThreadInterfaceData
|
||||
{
|
||||
void *data;
|
||||
int32 sync;
|
||||
};
|
||||
|
||||
static sem_id my_find_sem(const char *name)
|
||||
{
|
||||
sem_id ret = B_ERROR;
|
||||
|
||||
/* Get the sem_info for every sempahore in this team. */
|
||||
sem_info info;
|
||||
int32 cookie = 0;
|
||||
|
||||
while(get_next_sem_info(0, &cookie, &info) == B_OK)
|
||||
if(strcmp(name, info.name) == 0)
|
||||
{
|
||||
ret = info.sem;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
TimerManager nsTimerBeOS::sTimerManager;
|
||||
|
||||
TimerManager::TimerManager()
|
||||
: BList(40)
|
||||
{
|
||||
mQuitRequested = false;
|
||||
mSyncSem = create_sem(0, "timer sync");
|
||||
if(mSyncSem < 0)
|
||||
debugger("Failed to create sem...");
|
||||
|
||||
mTimerThreadID = spawn_thread(&sTimerThreadFunc, "timer roster", B_URGENT_DISPLAY_PRIORITY, (void *)this);
|
||||
if(mTimerThreadID < B_OK)
|
||||
// is it the right way ?
|
||||
debugger("Failed to spawn timer thread...");
|
||||
|
||||
resume_thread(mTimerThreadID);
|
||||
}
|
||||
|
||||
TimerManager::~TimerManager()
|
||||
{
|
||||
// should we empty the list here and NS_RELEASE ?
|
||||
mQuitRequested = true;
|
||||
delete_sem(mSyncSem);
|
||||
|
||||
int32 junk;
|
||||
wait_for_thread(mTimerThreadID, &junk);
|
||||
}
|
||||
|
||||
void TimerManager::AddRequest(nsITimer *inRequest)
|
||||
{
|
||||
if(mLocker.Lock())
|
||||
{
|
||||
NS_ADDREF(inRequest); // this is for the timer list
|
||||
|
||||
// insert sorted into timer event list
|
||||
int32 count = CountItems();
|
||||
int32 pos;
|
||||
for(pos = 0; pos < count; pos++)
|
||||
{
|
||||
nsITimer *entry = (nsITimer *)ItemAtFast(pos);
|
||||
if(((nsTimerBeOS *)entry)->mSchedTime > ((nsTimerBeOS*)inRequest)->mSchedTime)
|
||||
break;
|
||||
}
|
||||
AddItem(inRequest, pos);
|
||||
|
||||
if(pos == 0)
|
||||
// We need to wake the thread to wait on the newly added event
|
||||
release_sem(mSyncSem);
|
||||
|
||||
mLocker.Unlock();
|
||||
}
|
||||
}
|
||||
|
||||
bool TimerManager::RemoveRequest(nsITimer *inRequest)
|
||||
{
|
||||
bool found = false;
|
||||
|
||||
if(mLocker.Lock())
|
||||
{
|
||||
if(RemoveItem(inRequest))
|
||||
{
|
||||
NS_RELEASE(inRequest);
|
||||
found = true;
|
||||
}
|
||||
|
||||
mLocker.Unlock();
|
||||
}
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
int32 TimerManager::sTimerThreadFunc(void *inData)
|
||||
{
|
||||
return ((TimerManager *)inData)->TimerThreadFunc();
|
||||
}
|
||||
|
||||
int32 TimerManager::TimerThreadFunc()
|
||||
{
|
||||
char portname[64];
|
||||
char semname[64];
|
||||
port_id eventport;
|
||||
sem_id syncsem;
|
||||
PRThread *cached = (PRThread *)-1;
|
||||
|
||||
while(! mQuitRequested)
|
||||
{
|
||||
nsITimer *tobj = 0;
|
||||
|
||||
mLocker.Lock();
|
||||
|
||||
bigtime_t now = system_time();
|
||||
|
||||
// Fire expired pending requests
|
||||
while((tobj = FirstRequest()) != 0 && ((nsTimerBeOS*)tobj)->mSchedTime <= now)
|
||||
{
|
||||
nsTimerBeOS *tobjbeos = (nsTimerBeOS *)tobj;
|
||||
|
||||
RemoveItem((int32)0);
|
||||
mLocker.Unlock();
|
||||
|
||||
if(! tobjbeos->mCanceled)
|
||||
{
|
||||
// fire it
|
||||
if(tobjbeos->mThread != cached)
|
||||
{
|
||||
sprintf(portname, "event%lx", (uint32)tobjbeos->mThread);
|
||||
sprintf(semname, "sync%lx", (uint32)tobjbeos->mThread);
|
||||
|
||||
eventport = find_port(portname);
|
||||
syncsem = my_find_sem(semname);
|
||||
cached = tobjbeos->mThread;
|
||||
}
|
||||
|
||||
// call timer synchronously so we're sure tobj is alive
|
||||
ThreadInterfaceData id;
|
||||
id.data = tobjbeos;
|
||||
id.sync = true;
|
||||
if(write_port(eventport, 'WMti', &id, sizeof(id)) == B_OK)
|
||||
while(acquire_sem(syncsem) == B_INTERRUPTED)
|
||||
;
|
||||
}
|
||||
NS_RELEASE(tobjbeos);
|
||||
|
||||
mLocker.Lock();
|
||||
}
|
||||
mLocker.Unlock();
|
||||
|
||||
if(acquire_sem_etc(mSyncSem, 1, B_ABSOLUTE_TIMEOUT,
|
||||
tobj ? ((nsTimerBeOS *)tobj)->mSchedTime : B_INFINITE_TIMEOUT) == B_BAD_SEM_ID)
|
||||
break;
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
//
|
||||
// nsTimerBeOS
|
||||
//
|
||||
void nsTimerBeOS::FireTimeout()
|
||||
{
|
||||
if( ! mCanceled)
|
||||
{
|
||||
if(mFunc != NULL)
|
||||
(*mFunc)(this, mClosure); // If there's a function, call it.
|
||||
else if(mCallback != NULL)
|
||||
mCallback->Notify(this); // But if there's an interface, notify it.
|
||||
}
|
||||
}
|
||||
|
||||
nsTimerBeOS::nsTimerBeOS()
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
mFunc = 0;
|
||||
mCallback = 0;
|
||||
mDelay = 0;
|
||||
mClosure = 0;
|
||||
mSchedTime = 0;
|
||||
mCanceled = false;
|
||||
}
|
||||
|
||||
nsTimerBeOS::~nsTimerBeOS()
|
||||
{
|
||||
Cancel();
|
||||
NS_IF_RELEASE(mCallback);
|
||||
}
|
||||
|
||||
void nsTimerBeOS::SetDelay(PRUint32 aDelay)
|
||||
{
|
||||
mDelay = aDelay;
|
||||
mSchedTime = system_time() + mDelay * 1000;
|
||||
|
||||
NS_ADDREF(this);
|
||||
if (nsTimerBeOS::sTimerManager.RemoveRequest(this))
|
||||
nsTimerBeOS::sTimerManager.AddRequest(this);
|
||||
Release();
|
||||
}
|
||||
|
||||
void nsTimerBeOS::SetPriority(PRUint32 aPriority)
|
||||
{
|
||||
mPriority = aPriority;
|
||||
}
|
||||
|
||||
void nsTimerBeOS::SetType(PRUint32 aType)
|
||||
{
|
||||
mType = aType;
|
||||
}
|
||||
|
||||
nsresult nsTimerBeOS::Init(nsTimerCallbackFunc aFunc, void *aClosure,
|
||||
PRUint32 aDelay, PRUint32 aPriority, PRUint32 aType)
|
||||
{
|
||||
mFunc = aFunc;
|
||||
mClosure = aClosure;
|
||||
|
||||
return Init(aDelay);
|
||||
}
|
||||
|
||||
nsresult nsTimerBeOS::Init(nsITimerCallback *aCallback,
|
||||
PRUint32 aDelay, PRUint32 aPriority, PRUint32 aType)
|
||||
{
|
||||
mCallback = aCallback;
|
||||
NS_ADDREF(mCallback);
|
||||
|
||||
return Init(aDelay);
|
||||
}
|
||||
|
||||
|
||||
nsresult nsTimerBeOS::Init(PRUint32 aDelay)
|
||||
{
|
||||
mDelay = aDelay;
|
||||
NS_ADDREF(this); // this is for clients of the timer
|
||||
mSchedTime = system_time() + aDelay * 1000;
|
||||
|
||||
mThread = PR_GetCurrentThread();
|
||||
|
||||
sTimerManager.AddRequest(this);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsTimerBeOS, kITimerIID);
|
||||
|
||||
|
||||
void nsTimerBeOS::Cancel()
|
||||
{
|
||||
mCanceled = true;
|
||||
nsTimerBeOS::sTimerManager.RemoveRequest(this);
|
||||
}
|
||||
|
||||
nsresult NS_NewTimer(nsITimer** aInstancePtrResult)
|
||||
{
|
||||
NS_PRECONDITION(nsnull != aInstancePtrResult, "null ptr");
|
||||
if(nsnull == aInstancePtrResult)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
nsTimerBeOS *timer = new nsTimerBeOS();
|
||||
if(nsnull == timer)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
return timer->QueryInterface(kITimerIID, (void **) aInstancePtrResult);
|
||||
}
|
||||
|
||||
|
||||
110
mozilla/widget/timer/src/beos/nsTimerBeOS.h
Normal file
110
mozilla/widget/timer/src/beos/nsTimerBeOS.h
Normal file
@ -0,0 +1,110 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
|
||||
#ifndef __nsTimerBeOS_h
|
||||
#define __nsTimerBeOS_h
|
||||
|
||||
#include "nsITimer.h"
|
||||
#include "nsITimerCallback.h"
|
||||
|
||||
#include <prthread.h>
|
||||
|
||||
#include <List.h>
|
||||
#include <Autolock.h>
|
||||
|
||||
class TimerManager : public BList
|
||||
{
|
||||
public:
|
||||
TimerManager();
|
||||
~TimerManager();
|
||||
void AddRequest(nsITimer *inRequest);
|
||||
bool RemoveRequest(nsITimer *inRequest);
|
||||
|
||||
private:
|
||||
BLocker mLocker;
|
||||
sem_id mSyncSem;
|
||||
thread_id mTimerThreadID;
|
||||
bool mQuitRequested;
|
||||
|
||||
static int32 sTimerThreadFunc(void *);
|
||||
int32 TimerThreadFunc();
|
||||
nsITimer *FirstRequest() { return (nsITimer *)FirstItem(); }
|
||||
};
|
||||
|
||||
class nsTimerBeOS : public nsITimer
|
||||
{
|
||||
friend class TimerManager;
|
||||
public:
|
||||
|
||||
nsTimerBeOS();
|
||||
virtual ~nsTimerBeOS();
|
||||
|
||||
virtual nsresult Init(nsTimerCallbackFunc aFunc,
|
||||
void *aClosure,
|
||||
PRUint32 aDelay,
|
||||
PRUint32 aPriority = NS_PRIORITY_NORMAL,
|
||||
PRUint32 aType = NS_TYPE_ONE_SHOT
|
||||
);
|
||||
|
||||
virtual nsresult Init(nsITimerCallback *aCallback,
|
||||
PRUint32 aDelay,
|
||||
PRUint32 aPriority = NS_PRIORITY_NORMAL,
|
||||
PRUint32 aType = NS_TYPE_ONE_SHOT
|
||||
);
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
virtual void Cancel();
|
||||
|
||||
virtual PRUint32 GetDelay() { return mDelay; }
|
||||
virtual void SetDelay(PRUint32 aDelay);
|
||||
|
||||
virtual PRUint32 GetPriority() { return mPriority; }
|
||||
virtual void SetPriority(PRUint32 aPriority);
|
||||
|
||||
virtual PRUint32 GetType() { return mType; }
|
||||
virtual void SetType(PRUint32 aType);
|
||||
|
||||
virtual void* GetClosure() { return mClosure; }
|
||||
|
||||
NS_IMETHOD_(void) FireTimeout();
|
||||
|
||||
bigtime_t mSchedTime; // Time when this request should be done
|
||||
PRUint32 mDelay; // The delay set in Init()
|
||||
private:
|
||||
nsresult Init(PRUint32 aDelay); // Initialize the timer.
|
||||
|
||||
PRUint32 mPriority;
|
||||
PRUint32 mType;
|
||||
nsTimerCallbackFunc mFunc; // The function to call back when expired
|
||||
void * mClosure; // The argumnet to pass it.
|
||||
nsITimerCallback * mCallback; // An interface to notify when expired.
|
||||
|
||||
bool mCanceled;
|
||||
PRThread * mThread;
|
||||
// PRBool mRepeat; // A repeat, not implemented yet.
|
||||
|
||||
public:
|
||||
static TimerManager sTimerManager;
|
||||
};
|
||||
|
||||
#endif // __nsTimerBeOS_h
|
||||
44
mozilla/widget/timer/src/beos/nsTimerBeOSFactory.cpp
Normal file
44
mozilla/widget/timer/src/beos/nsTimerBeOSFactory.cpp
Normal file
@ -0,0 +1,44 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indentT-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
|
||||
#include "nsIGenericFactory.h"
|
||||
#include "nsIModule.h"
|
||||
#include "nsCOMPtr.h"
|
||||
|
||||
#include "nsTimerBeOS.h"
|
||||
|
||||
// {48B62AD2-48D3-11d3-B224-000064657374}
|
||||
#define NS_TIMER_BEOS_CID \
|
||||
{ 0x48b62ad2, 0x48d3, 0x11d3, \
|
||||
{ 0xb2, 0x24, 0x0, 0x0, 0x64, 0x65, 0x73, 0x74 } }
|
||||
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsTimerBeOS)
|
||||
|
||||
static nsModuleComponentInfo components[] =
|
||||
{
|
||||
{ "BeOS timer",
|
||||
NS_TIMER_BEOS_CID,
|
||||
"@mozilla.org/timer;1",
|
||||
nsTimerBeOSConstructor }
|
||||
};
|
||||
|
||||
NS_IMPL_NSGETMODULE("nsBeOSTimerModule", components)
|
||||
Loading…
x
Reference in New Issue
Block a user