зеркало из https://github.com/mozilla/pjs.git
Fix for bug 69285 "Mozilla is unresponsive after sleep", patch=sfraser, gordon, r=wtc.
This commit is contained in:
Родитель
dc62e0708c
Коммит
bc75f6605c
|
@ -132,6 +132,193 @@ PR_IMPLEMENT(PRStatus) PR_WaitForPollableEvent(PRFileDesc *event)
|
|||
return PR_SUCCESS;
|
||||
}
|
||||
|
||||
#elif defined (XP_MAC)
|
||||
|
||||
#include "primpl.h"
|
||||
|
||||
/*
|
||||
* On Mac, local sockets cannot be used, because the networking stack
|
||||
* closes them when the machine goes to sleep. Instead, we'll use a simple
|
||||
* flag.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* PRFilePrivate structure for the NSPR pollable events layer
|
||||
*/
|
||||
typedef struct PRPollableDesc {
|
||||
PRBool gotEvent;
|
||||
PRThread *pollingThread;
|
||||
} PRPollableDesc;
|
||||
|
||||
static PRStatus PR_CALLBACK _pr_MacPolEvtClose(PRFileDesc *fd);
|
||||
|
||||
static PRInt16 PR_CALLBACK _pr_MacPolEvtPoll(
|
||||
PRFileDesc *fd, PRInt16 in_flags, PRInt16 *out_flags);
|
||||
|
||||
static PRIOMethods _pr_mac_polevt_methods = {
|
||||
PR_DESC_LAYERED,
|
||||
_pr_MacPolEvtClose,
|
||||
(PRReadFN)_PR_InvalidInt,
|
||||
(PRWriteFN)_PR_InvalidInt,
|
||||
(PRAvailableFN)_PR_InvalidInt,
|
||||
(PRAvailable64FN)_PR_InvalidInt64,
|
||||
(PRFsyncFN)_PR_InvalidStatus,
|
||||
(PRSeekFN)_PR_InvalidInt,
|
||||
(PRSeek64FN)_PR_InvalidInt64,
|
||||
(PRFileInfoFN)_PR_InvalidStatus,
|
||||
(PRFileInfo64FN)_PR_InvalidStatus,
|
||||
(PRWritevFN)_PR_InvalidInt,
|
||||
(PRConnectFN)_PR_InvalidStatus,
|
||||
(PRAcceptFN)_PR_InvalidDesc,
|
||||
(PRBindFN)_PR_InvalidStatus,
|
||||
(PRListenFN)_PR_InvalidStatus,
|
||||
(PRShutdownFN)_PR_InvalidStatus,
|
||||
(PRRecvFN)_PR_InvalidInt,
|
||||
(PRSendFN)_PR_InvalidInt,
|
||||
(PRRecvfromFN)_PR_InvalidInt,
|
||||
(PRSendtoFN)_PR_InvalidInt,
|
||||
_pr_MacPolEvtPoll,
|
||||
(PRAcceptreadFN)_PR_InvalidInt,
|
||||
(PRTransmitfileFN)_PR_InvalidInt,
|
||||
(PRGetsocknameFN)_PR_InvalidStatus,
|
||||
(PRGetpeernameFN)_PR_InvalidStatus,
|
||||
(PRReservedFN)_PR_InvalidInt,
|
||||
(PRReservedFN)_PR_InvalidInt,
|
||||
(PRGetsocketoptionFN)_PR_InvalidStatus,
|
||||
(PRSetsocketoptionFN)_PR_InvalidStatus,
|
||||
(PRSendfileFN)_PR_InvalidInt,
|
||||
(PRReservedFN)_PR_InvalidInt,
|
||||
(PRReservedFN)_PR_InvalidInt,
|
||||
(PRReservedFN)_PR_InvalidInt,
|
||||
(PRReservedFN)_PR_InvalidInt,
|
||||
(PRReservedFN)_PR_InvalidInt
|
||||
};
|
||||
|
||||
static PRDescIdentity _pr_mac_polevt_id;
|
||||
static PRCallOnceType _pr_mac_polevt_once_control;
|
||||
static PRStatus PR_CALLBACK _pr_MacPolEvtInit(void);
|
||||
|
||||
static PRInt16 PR_CALLBACK _pr_MacPolEvtPoll(
|
||||
PRFileDesc *fd, PRInt16 in_flags, PRInt16 *out_flags)
|
||||
{
|
||||
PRPollableDesc *pollDesc = (PRPollableDesc *)fd->secret;
|
||||
PR_ASSERT(pollDesc);
|
||||
|
||||
// set the current thread so that we can wake up the poll thread
|
||||
pollDesc->pollingThread = PR_GetCurrentThread();
|
||||
|
||||
if ((in_flags & PR_POLL_READ) && pollDesc->gotEvent)
|
||||
*out_flags = PR_POLL_READ;
|
||||
else
|
||||
*out_flags = 0;
|
||||
return pollDesc->gotEvent ? 1 : 0;
|
||||
}
|
||||
|
||||
static PRStatus PR_CALLBACK _pr_MacPolEvtInit(void)
|
||||
{
|
||||
_pr_mac_polevt_id = PR_GetUniqueIdentity("NSPR pollable events");
|
||||
if (PR_INVALID_IO_LAYER == _pr_mac_polevt_id) {
|
||||
return PR_FAILURE;
|
||||
}
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
|
||||
static PRStatus PR_CALLBACK _pr_MacPolEvtClose(PRFileDesc *fd)
|
||||
{
|
||||
PRPollableDesc *pollDesc = (PRPollableDesc *)fd->secret;
|
||||
PR_ASSERT(NULL == fd->higher && NULL == fd->lower);
|
||||
PR_ASSERT(pollDesc);
|
||||
PR_DELETE(pollDesc);
|
||||
fd->dtor(fd);
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
|
||||
PR_IMPLEMENT(PRFileDesc *) PR_NewPollableEvent(void)
|
||||
{
|
||||
PRFileDesc *event;
|
||||
PRPollableDesc *pollDesc;
|
||||
|
||||
if (PR_CallOnce(&_pr_mac_polevt_once_control, _pr_MacPolEvtInit) == PR_FAILURE) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
event = PR_CreateIOLayerStub(_pr_mac_polevt_id, &_pr_mac_polevt_methods);
|
||||
if (NULL == event) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
** Allocate an event flag and clear it.
|
||||
*/
|
||||
pollDesc = PR_NEW(PRPollableDesc);
|
||||
if (!pollDesc) {
|
||||
PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
|
||||
goto errorExit;
|
||||
}
|
||||
|
||||
pollDesc->gotEvent = PR_FALSE;
|
||||
pollDesc->pollingThread = NULL;
|
||||
|
||||
event->secret = (PRFilePrivate*)pollDesc;
|
||||
return event;
|
||||
|
||||
errorExit:
|
||||
|
||||
if (event) {
|
||||
PR_DELETE(event->secret);
|
||||
event->dtor(event);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PR_IMPLEMENT(PRStatus) PR_DestroyPollableEvent(PRFileDesc *event)
|
||||
{
|
||||
return PR_Close(event);
|
||||
}
|
||||
|
||||
/* from macsockotpt.c. I wish there was a cleaner way */
|
||||
extern void WakeUpNotifiedThread(PRThread *thread, OTResult result);
|
||||
|
||||
PR_IMPLEMENT(PRStatus) PR_SetPollableEvent(PRFileDesc *event)
|
||||
{
|
||||
PRPollableDesc *pollDesc = (PRPollableDesc *)event->secret;
|
||||
PR_ASSERT(pollDesc);
|
||||
PR_ASSERT(pollDesc->pollingThread->state != _PR_DEAD_STATE);
|
||||
|
||||
if (pollDesc->pollingThread->state == _PR_DEAD_STATE)
|
||||
return PR_FAILURE;
|
||||
|
||||
pollDesc->gotEvent = PR_TRUE;
|
||||
|
||||
if (pollDesc->pollingThread)
|
||||
WakeUpNotifiedThread(pollDesc->pollingThread, noErr);
|
||||
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
|
||||
PR_IMPLEMENT(PRStatus) PR_WaitForPollableEvent(PRFileDesc *event)
|
||||
{
|
||||
PRPollableDesc *pollDesc = (PRPollableDesc *)event->secret;
|
||||
PRStatus status;
|
||||
PR_ASSERT(pollDesc);
|
||||
|
||||
/*
|
||||
FIXME: Danger Will Robinson!
|
||||
|
||||
The current implementation of PR_WaitForPollableEvent is somewhat
|
||||
bogus; it makes the assumption that, in Mozilla, this will only
|
||||
ever be called when PR_Poll has returned, telling us that an
|
||||
event has been set.
|
||||
*/
|
||||
|
||||
PR_ASSERT(pollDesc->gotEvent);
|
||||
|
||||
status = (pollDesc->gotEvent) ? PR_SUCCESS : PR_FAILURE;
|
||||
pollDesc->gotEvent = PR_FALSE;
|
||||
return status;
|
||||
}
|
||||
|
||||
#else /* VMS */
|
||||
|
||||
/*
|
||||
|
|
|
@ -74,6 +74,9 @@ static pascal void RawEndpointNotifierRoutine(void * contextPtr, OTEventCode co
|
|||
|
||||
static PRBool GetState(PRFileDesc *fd, PRBool *readReady, PRBool *writeReady, PRBool *exceptReady);
|
||||
|
||||
void
|
||||
WakeUpNotifiedThread(PRThread *thread, OTResult result);
|
||||
|
||||
extern void WaitOnThisThread(PRThread *thread, PRIntervalTime timeout);
|
||||
extern void DoneWaitingOnThisThread(PRThread *thread);
|
||||
|
||||
|
@ -283,7 +286,7 @@ static void PrepareForAsyncCompletion(PRThread * thread, PRInt32 osfd)
|
|||
}
|
||||
|
||||
|
||||
static void
|
||||
void
|
||||
WakeUpNotifiedThread(PRThread *thread, OTResult result)
|
||||
{
|
||||
_PRCPU * cpu = _PR_MD_CURRENT_CPU();
|
||||
|
@ -1739,37 +1742,39 @@ static PRInt32 CheckPollDescs(PRPollDesc *pds, PRIntn npds)
|
|||
|
||||
pd->out_flags = 0; /* pre-condition */
|
||||
bottomFD = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER);
|
||||
PR_ASSERT(NULL != bottomFD);
|
||||
|
||||
if (bottomFD && (_PR_FILEDESC_OPEN == bottomFD->secret->state))
|
||||
{
|
||||
if (GetState(bottomFD, &readReady, &writeReady, &exceptReady))
|
||||
{
|
||||
if (readReady)
|
||||
{
|
||||
if (in_flags_read & PR_POLL_READ)
|
||||
pd->out_flags |= PR_POLL_READ;
|
||||
if (in_flags_write & PR_POLL_READ)
|
||||
pd->out_flags |= PR_POLL_WRITE;
|
||||
}
|
||||
if (writeReady)
|
||||
{
|
||||
if (in_flags_read & PR_POLL_WRITE)
|
||||
pd->out_flags |= PR_POLL_READ;
|
||||
if (in_flags_write & PR_POLL_WRITE)
|
||||
pd->out_flags |= PR_POLL_WRITE;
|
||||
}
|
||||
if (exceptReady && (pd->in_flags & PR_POLL_EXCEPT))
|
||||
{
|
||||
pd->out_flags |= PR_POLL_EXCEPT;
|
||||
}
|
||||
if (0 != pd->out_flags) ready++;
|
||||
}
|
||||
}
|
||||
else /* bad state */
|
||||
/* bottomFD can be NULL for pollable sockets */
|
||||
if (bottomFD)
|
||||
{
|
||||
ready += 1; /* this will cause an abrupt return */
|
||||
pd->out_flags = PR_POLL_NVAL; /* bogii */
|
||||
if (_PR_FILEDESC_OPEN == bottomFD->secret->state)
|
||||
{
|
||||
if (GetState(bottomFD, &readReady, &writeReady, &exceptReady))
|
||||
{
|
||||
if (readReady)
|
||||
{
|
||||
if (in_flags_read & PR_POLL_READ)
|
||||
pd->out_flags |= PR_POLL_READ;
|
||||
if (in_flags_write & PR_POLL_READ)
|
||||
pd->out_flags |= PR_POLL_WRITE;
|
||||
}
|
||||
if (writeReady)
|
||||
{
|
||||
if (in_flags_read & PR_POLL_WRITE)
|
||||
pd->out_flags |= PR_POLL_READ;
|
||||
if (in_flags_write & PR_POLL_WRITE)
|
||||
pd->out_flags |= PR_POLL_WRITE;
|
||||
}
|
||||
if (exceptReady && (pd->in_flags & PR_POLL_EXCEPT))
|
||||
{
|
||||
pd->out_flags |= PR_POLL_EXCEPT;
|
||||
}
|
||||
if (0 != pd->out_flags) ready++;
|
||||
}
|
||||
}
|
||||
else /* bad state */
|
||||
{
|
||||
ready += 1; /* this will cause an abrupt return */
|
||||
pd->out_flags = PR_POLL_NVAL; /* bogii */
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1788,7 +1793,6 @@ static void SetDescPollThread(PRPollDesc *pds, PRIntn npds, PRThread* thread)
|
|||
if (pd->fd)
|
||||
{
|
||||
PRFileDesc *bottomFD = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER);
|
||||
PR_ASSERT(NULL != bottomFD);
|
||||
if (bottomFD && (_PR_FILEDESC_OPEN == bottomFD->secret->state))
|
||||
{
|
||||
bottomFD->secret->md.poll.thread = thread;
|
||||
|
|
Загрузка…
Ссылка в новой задаче