Applying Mac changes
This commit is contained in:
Родитель
a994a58f69
Коммит
fc0a04baa1
|
@ -61,6 +61,7 @@
|
|||
#include "profile.h"
|
||||
#include "prefs.h"
|
||||
#include "ocsp.h"
|
||||
|
||||
#ifdef XP_MAC
|
||||
#include "macshell.h"
|
||||
#endif
|
||||
|
@ -414,9 +415,6 @@ SSMStatus SSMControlConnection_Shutdown(SSMResource *arg, SSMStatus status)
|
|||
return rv;
|
||||
}
|
||||
|
||||
#ifdef XP_MAC
|
||||
extern PRBool gShouldQuit;
|
||||
#endif
|
||||
|
||||
SSMStatus SSMControlConnection_Destroy(SSMResource *res,
|
||||
PRBool doFree)
|
||||
|
@ -468,7 +466,7 @@ SSMStatus SSMControlConnection_Destroy(SSMResource *res,
|
|||
SSM_ReleaseLockFile();
|
||||
#endif
|
||||
#ifdef XP_MAC
|
||||
gShouldQuit = PR_TRUE; // tell primordial thread to quit
|
||||
SetQuitFlag(PR_TRUE); // tell primordial thread to quit
|
||||
#else
|
||||
exit(0);
|
||||
#endif
|
||||
|
@ -824,7 +822,8 @@ ssm_certdb_name_cb(void *arg, int dbVersion)
|
|||
|
||||
#ifdef XP_MAC
|
||||
/* on Mac, :: means parent directory. does non-Mac get // with Seamonkey? */
|
||||
return PR_smprintf("%sCertificates%s", configdir, dbver);
|
||||
PR_ASSERT(configdir[strlen(configdir) - 1] == ':');
|
||||
return PR_smprintf("%sCertificates%s", configdir, dbver);
|
||||
#else
|
||||
return PR_smprintf("%s/cert%s.db", configdir, dbver);
|
||||
#endif
|
||||
|
@ -845,7 +844,8 @@ static char *ssm_keydb_name_cb(void *arg, int dbVersion)
|
|||
break;
|
||||
}
|
||||
#ifdef XP_MAC
|
||||
return PR_smprintf("%s:Key Database%s", configdir, dbver);
|
||||
PR_ASSERT(configdir[strlen(configdir) - 1] == ':');
|
||||
return PR_smprintf("%sKey Database%s", configdir, dbver);
|
||||
#else
|
||||
return PR_smprintf("%s/key%s.db", configdir, dbver);
|
||||
#endif
|
||||
|
@ -925,7 +925,8 @@ ssm_OpenSecModDB(const char * configdir)
|
|||
#ifdef XP_UNIX
|
||||
secmodname = PR_smprintf("%s/secmodule.db", configdir);
|
||||
#elif defined(XP_MAC)
|
||||
secmodname = PR_smprintf("%s:Security Modules", configdir);
|
||||
PR_ASSERT(configdir[strlen(configdir) - 1] == ':');
|
||||
secmodname = PR_smprintf("%sSecurity Modules", configdir);
|
||||
#else
|
||||
secmodname = PR_smprintf("%s/secmod.db", configdir);
|
||||
#endif
|
||||
|
@ -951,26 +952,7 @@ ssm_ShutdownNSS(SSMControlConnection *ctrl)
|
|||
SSMPolicyType
|
||||
SSM_ConvertSVRPlcyToSSMPolicy(PRInt32 policy)
|
||||
{
|
||||
SSMPolicyType retVal;
|
||||
switch (policy) {
|
||||
#ifdef XP_MAC
|
||||
default:
|
||||
#endif
|
||||
case SVRPLCYDomestic:
|
||||
retVal = ssmDomestic;
|
||||
break;
|
||||
case SVRPLCYExport:
|
||||
retVal = ssmExport;
|
||||
break;
|
||||
case SVRPLCYFrance:
|
||||
retVal = ssmFrance;
|
||||
break;
|
||||
#ifndef XP_MAC
|
||||
default:
|
||||
retVal = ssmUnknownPolicy;
|
||||
#endif
|
||||
}
|
||||
return retVal;
|
||||
return ssmDomestic;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -1,439 +0,0 @@
|
|||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Mozilla 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/MPL/
|
||||
*
|
||||
* 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 the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
#include "connect.h"
|
||||
#include "dataconn.h"
|
||||
#include "ctrlconn.h"
|
||||
#include "servimpl.h"
|
||||
#include "serv.h"
|
||||
#include "ssmerrs.h"
|
||||
|
||||
#define SSMCONNECTION(p) (&(p)->super)
|
||||
#define SSMRESOURCE(p) (&(p)->super.super)
|
||||
|
||||
/* How many milliseconds to wait for client input */
|
||||
#define SSM_READCLIENT_POKE_INTERVAL 30000
|
||||
|
||||
|
||||
SSMStatus SSMDataConnection_Create(void *arg, SSMControlConnection * connection,
|
||||
SSMResource **res)
|
||||
{
|
||||
SSMStatus rv = PR_SUCCESS;
|
||||
SSMDataConnection *conn;
|
||||
*res = NULL; /* in case we fail */
|
||||
|
||||
conn = (SSMDataConnection *) PR_CALLOC(sizeof(SSMDataConnection));
|
||||
if (!conn) goto loser;
|
||||
|
||||
rv = SSMDataConnection_Init(conn, (SSMControlConnection *) arg,
|
||||
SSM_RESTYPE_DATA_CONNECTION);
|
||||
if (rv != PR_SUCCESS) goto loser;
|
||||
|
||||
SSMDataConnection_Invariant(conn);
|
||||
|
||||
*res = SSMRESOURCE(conn);
|
||||
return PR_SUCCESS;
|
||||
|
||||
loser:
|
||||
if (rv == PR_SUCCESS) rv = PR_FAILURE;
|
||||
|
||||
if (conn)
|
||||
{
|
||||
SSM_ShutdownResource(SSMRESOURCE(conn), rv);
|
||||
SSM_FreeResource(SSMRESOURCE(conn));
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
SSMStatus SSMDataConnection_Init(SSMDataConnection *conn,
|
||||
SSMControlConnection *parent,
|
||||
SSMResourceType type)
|
||||
{
|
||||
SSMStatus rv = PR_SUCCESS;
|
||||
SSMResourceType parentType = RESOURCE_CLASS(parent);
|
||||
|
||||
PR_ASSERT(parent != NULL);
|
||||
PR_ASSERT((parentType == SSM_RESTYPE_CONTROL_CONNECTION) || (parentType == SSM_RESTYPE_CONNECTION));
|
||||
if (!parent) goto loser;
|
||||
rv = SSMConnection_Init(parent, SSMCONNECTION(conn), type);
|
||||
if (rv != PR_SUCCESS) goto loser;
|
||||
|
||||
/* Initialize data shutdown queue. */
|
||||
conn->m_shutdownQ = SSM_NewCollection();
|
||||
if (conn->m_shutdownQ == NULL) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Hang our shutdown func. */
|
||||
SSMCONNECTION(conn)->m_auth_func = SSMDataConnection_Authenticate;
|
||||
|
||||
return PR_SUCCESS;
|
||||
|
||||
loser:
|
||||
if (rv == PR_SUCCESS) rv = PR_FAILURE;
|
||||
return rv;
|
||||
}
|
||||
|
||||
SSMStatus SSMDataConnection_Destroy(SSMResource *res, PRBool doFree)
|
||||
{
|
||||
SSMDataConnection *conn = (SSMDataConnection *) res;
|
||||
|
||||
/* We should be shut down. */
|
||||
PR_ASSERT(res->m_threadCount == 0);
|
||||
|
||||
/* Drain and destroy the queue. */
|
||||
if (conn->m_shutdownQ) {
|
||||
ssm_DrainAndDestroyQueue(&(conn->m_shutdownQ));
|
||||
}
|
||||
|
||||
/* Destroy superclass fields. */
|
||||
SSMConnection_Destroy(&(conn->super.super), PR_FALSE);
|
||||
|
||||
/* Free the connection object if asked. */
|
||||
if (doFree)
|
||||
PR_DELETE(conn);
|
||||
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
|
||||
void
|
||||
SSMDataConnection_Invariant(SSMDataConnection *conn)
|
||||
{
|
||||
if (conn)
|
||||
{
|
||||
SSMConnection_Invariant(&conn->super);
|
||||
SSM_LockResource(SSMRESOURCE(conn));
|
||||
PR_ASSERT(SSM_IsAKindOf(SSMRESOURCE(conn), SSM_RESTYPE_DATA_CONNECTION));
|
||||
PR_ASSERT(conn->m_shutdownQ != NULL);
|
||||
SSM_UnlockResource(SSMRESOURCE(conn));
|
||||
}
|
||||
}
|
||||
|
||||
SSMStatus
|
||||
SSMDataConnection_GetAttrIDs(SSMResource *res,
|
||||
SSMAttributeID **ids,
|
||||
PRIntn *count)
|
||||
{
|
||||
SSMStatus rv;
|
||||
|
||||
rv = SSMConnection_GetAttrIDs(res, ids, count);
|
||||
if (rv != PR_SUCCESS)
|
||||
goto loser;
|
||||
|
||||
*ids = (SSMAttributeID *) PR_REALLOC(*ids, (*count + 1) * sizeof(SSMAttributeID));
|
||||
if (! *ids) goto loser;
|
||||
|
||||
(*ids)[*count++] = SSM_FID_CONN_DATA_PENDING;
|
||||
|
||||
goto done;
|
||||
loser:
|
||||
if (rv == PR_SUCCESS) rv = PR_FAILURE;
|
||||
done:
|
||||
return rv;
|
||||
}
|
||||
|
||||
SSMStatus
|
||||
SSMDataConnection_GetAttr(SSMResource *res,
|
||||
SSMAttributeID attrID,
|
||||
SSMResourceAttrType attrType,
|
||||
SSMAttributeValue *value)
|
||||
{
|
||||
SSMStatus rv = PR_SUCCESS;
|
||||
|
||||
/* see what it is */
|
||||
switch(attrID)
|
||||
{
|
||||
case SSM_FID_CONN_DATA_PENDING:
|
||||
/* this is not used: will set it to zero for now */
|
||||
*(PRUint32*)value->u.numeric = (PRUint32)0;
|
||||
value->type = SSM_NUMERIC_ATTRIBUTE;
|
||||
break;
|
||||
|
||||
default:
|
||||
rv = SSMConnection_GetAttr(res,attrID,attrType,value);
|
||||
if (rv != PR_SUCCESS) goto loser;
|
||||
}
|
||||
|
||||
goto done;
|
||||
loser:
|
||||
value->type = SSM_NO_ATTRIBUTE;
|
||||
|
||||
done:
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
SSMStatus SSMDataConnection_SetupClientSocket(SSMDataConnection* conn)
|
||||
{
|
||||
SSMControlConnection* parent = NULL;
|
||||
char* pNonce;
|
||||
char* temp = NULL; /* for nonce verification */
|
||||
PRFileDesc* socket = NULL; /* client socket */
|
||||
PRNetAddr clientAddr;
|
||||
SSMStatus status = PR_FAILURE;
|
||||
PRIntn read;
|
||||
|
||||
PR_ASSERT(conn != NULL);
|
||||
|
||||
/* Allocate a nonce-sized chunk of memory to read into.
|
||||
(See below.) */
|
||||
parent = (SSMControlConnection*)(conn->super.m_parent);
|
||||
PR_ASSERT(parent != NULL);
|
||||
pNonce = parent->m_nonce;
|
||||
PR_ASSERT(pNonce != NULL);
|
||||
SSM_DEBUG("I think my parent's nonce is `%s'.\n", pNonce);
|
||||
|
||||
temp = (char*)PORT_ZAlloc(strlen(pNonce));
|
||||
|
||||
while ((socket == NULL) && (SSMRESOURCE(conn)->m_status == PR_SUCCESS)) {
|
||||
SSM_DEBUG("accepting next connect.\n");
|
||||
|
||||
/* Wait forever for a connection. (for now) */
|
||||
socket = PR_Accept(SSMRESOURCE(conn)->m_connection->m_dataSocket,
|
||||
&clientAddr, PR_INTERVAL_NO_TIMEOUT);
|
||||
SSM_DEBUG("accepted connection.\n");
|
||||
|
||||
if ((SSMRESOURCE(conn)->m_status != PR_SUCCESS) && socket) {
|
||||
/* May have gotten a socket, but we're shutting down.
|
||||
Close and zero out the socket. */
|
||||
PR_Close(socket);
|
||||
SSM_LockResource(SSMRESOURCE(conn));
|
||||
socket = conn->m_clientSocket = NULL;
|
||||
SSM_UnlockResource(SSMRESOURCE(conn));
|
||||
}
|
||||
|
||||
if (socket && !SSM_SocketPeerCheck(socket, PR_FALSE))
|
||||
{
|
||||
/*
|
||||
Failed peer check. Close socket and listen again.
|
||||
### mwelch - Could have a denial of service attack here if
|
||||
someone keeps trying to connect to this port.
|
||||
*/
|
||||
PR_Close(socket);
|
||||
socket = NULL;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (socket) {
|
||||
SSM_LockResource(SSMRESOURCE(conn));
|
||||
conn->m_clientSocket = socket;
|
||||
SSM_UnlockResource(SSMRESOURCE(conn));
|
||||
|
||||
SSM_DEBUG("reading/verifying nonce.\n");
|
||||
status = PR_SUCCESS;
|
||||
|
||||
/* Read the nonce from the client. If we didn't get the right
|
||||
nonce, reject the connection. */
|
||||
if ((temp) && (pNonce != NULL)) {
|
||||
read = SSM_ReadThisMany(socket, temp, strlen(pNonce));
|
||||
if ((unsigned int)read != strlen(pNonce)) {
|
||||
status = PR_GetError();
|
||||
}
|
||||
}
|
||||
|
||||
if ((status != PR_SUCCESS) || (memcmp(temp, pNonce,
|
||||
strlen(pNonce)))) {
|
||||
#ifdef DEBUG
|
||||
char thing1[255];
|
||||
char thing2[255];
|
||||
|
||||
strncpy(thing1, temp, strlen(pNonce));
|
||||
strncpy(thing2, temp, strlen(pNonce));
|
||||
/* Bad nonce, no biscuit! Shut down connection
|
||||
and wait for another on the data port. */
|
||||
SSM_DEBUG("Bad nonce, no biscuit!\n");
|
||||
SSM_DEBUG("(`%s' != `%s')\n", thing1, thing2);
|
||||
#endif
|
||||
SSM_LockResource(SSMRESOURCE(conn));
|
||||
PR_Close(conn->m_clientSocket);
|
||||
conn->m_clientSocket = socket = NULL;
|
||||
SSM_UnlockResource(SSMRESOURCE(conn));
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* Tear everything down, didn't get a connection. */
|
||||
SSM_DEBUG("Shutdown during connection setup.\n");
|
||||
goto loser;
|
||||
}
|
||||
}
|
||||
|
||||
SSM_DEBUG("Nonce is valid.\n");
|
||||
|
||||
/* We have a socket. Close the data port. */
|
||||
SSM_LockResource(SSMRESOURCE(conn));
|
||||
SSM_DEBUG("Socket is %ld.\n", socket);
|
||||
SSM_UnlockResource(SSMRESOURCE(conn));
|
||||
loser:
|
||||
if (temp != NULL) {
|
||||
PR_Free(temp);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
SSMStatus SSMDataConnection_ReadFromSocket(SSMDataConnection* conn,
|
||||
PRInt32* read,
|
||||
char* buffer)
|
||||
{
|
||||
SSMStatus status;
|
||||
#if 0
|
||||
SSMStatus osStat;
|
||||
char statBuf[256];
|
||||
#endif
|
||||
|
||||
PR_ASSERT(conn != NULL);
|
||||
PR_ASSERT(buffer != NULL);
|
||||
|
||||
/* Attempt to read LINESIZE bytes from the socket. */
|
||||
do {
|
||||
SSM_DEBUG("Attempting to read %ld bytes.\n", *read);
|
||||
*read = PR_Recv(conn->m_clientSocket, buffer, *read, 0,
|
||||
PR_MillisecondsToInterval(SSM_READCLIENT_POKE_INTERVAL));
|
||||
if (*read < 0) {
|
||||
status = PR_GetError(); /* save status for later use */
|
||||
#if 0
|
||||
osStat = PR_GetOSError(); /* just for fun */
|
||||
PR_GetErrorText(statBuf);
|
||||
#endif
|
||||
}
|
||||
SSM_DEBUG("Got %ld bytes of data, status == %ld.\n", (long)(*read),
|
||||
(long)status);
|
||||
}
|
||||
while ((*read == -1) && (status == PR_IO_TIMEOUT_ERROR) &&
|
||||
SSMRESOURCE(conn)->m_status == PR_SUCCESS);
|
||||
|
||||
/* Don't mask an error if we got one, but set it if we didn't get any
|
||||
* data (because that indicates a socket closure).
|
||||
*/
|
||||
if ((*read < 0) && (status == PR_SUCCESS)) {
|
||||
status = PR_FAILURE;
|
||||
}
|
||||
else if (*read >= 0) {
|
||||
status = PR_SUCCESS; /* clear the error from when we waited */
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* Null terminate the buffer so that we can dump it. */
|
||||
if (*read >= 0) {
|
||||
buffer[*read] = '\0';
|
||||
}
|
||||
#endif
|
||||
if (*read > 0) {
|
||||
SSM_DEBUG("got %ld bytes of data: <%s>\n", *read, buffer);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
SSMStatus
|
||||
SSMDataConnection_Shutdown(SSMResource *res, SSMStatus status)
|
||||
{
|
||||
SSMStatus rv, trv;
|
||||
PRThread *closer = PR_GetCurrentThread();
|
||||
|
||||
SSMDataConnection *conn = (SSMDataConnection *) res;
|
||||
/* SSMDataConnection_Invariant(conn); -- could be called from loser */
|
||||
|
||||
/* Lock down the resource before shutting it down */
|
||||
SSM_LockResource(SSMRESOURCE(conn));
|
||||
|
||||
/* If we're called from a service thread, clear that thread's
|
||||
place in the connection object so it doesn't get interrupted */
|
||||
if ((closer == conn->m_dataServiceThread) && (closer != NULL)) {
|
||||
conn->m_dataServiceThread = NULL;
|
||||
|
||||
/* Decrement living thread counter */
|
||||
SSMRESOURCE(conn)->m_threadCount--;
|
||||
}
|
||||
|
||||
/* shut down base class */
|
||||
rv = SSMConnection_Shutdown(res, status);
|
||||
|
||||
if ((SSMRESOURCE(conn)->m_status != PR_SUCCESS) &&
|
||||
(rv != SSM_ERR_ALREADY_SHUT_DOWN) &&
|
||||
(conn->m_clientSocket != NULL))
|
||||
{
|
||||
SSM_DEBUG("Shutting down data connection abnormally (rv == %d).\n",
|
||||
SSMRESOURCE(conn)->m_status);
|
||||
SSM_DEBUG("shutting down client socket.\n");
|
||||
PR_Shutdown(conn->m_clientSocket, PR_SHUTDOWN_SEND);
|
||||
|
||||
/* if this is called by a control thread, send a message to the
|
||||
* data service thread to shut down
|
||||
*/
|
||||
if ((closer != conn->m_dataServiceThread) &&
|
||||
(conn->m_shutdownQ != NULL)) {
|
||||
SSM_DEBUG("Send shutdown msg to data Q.\n");
|
||||
trv = SSM_SendQMessage(conn->m_shutdownQ, SSM_PRIORITY_SHUTDOWN,
|
||||
SSM_DATA_PROVIDER_SHUTDOWN, 0, NULL,
|
||||
PR_TRUE);
|
||||
}
|
||||
|
||||
if (conn->m_dataServiceThread) {
|
||||
PR_Interrupt(conn->m_dataServiceThread);
|
||||
}
|
||||
}
|
||||
|
||||
/* If the client sockets is/are now unused, close them. */
|
||||
if (SSMRESOURCE(conn)->m_threadCount == 0)
|
||||
{
|
||||
/* Close the client socket with linger */
|
||||
if (conn->m_clientSocket)
|
||||
{
|
||||
SSM_DEBUG("Close data socket.\n");
|
||||
trv = PR_Close(conn->m_clientSocket);
|
||||
conn->m_clientSocket = NULL;
|
||||
SSM_DEBUG("Closed client socket (rv == %d).\n",trv);
|
||||
}
|
||||
}
|
||||
|
||||
SSM_UnlockResource(SSMRESOURCE(conn));
|
||||
|
||||
return rv; /* so that subclasses know to perform shutdown */
|
||||
}
|
||||
|
||||
SSMStatus
|
||||
SSMDataConnection_Authenticate(SSMConnection *arg, char *nonce)
|
||||
{
|
||||
SSMStatus rv = SSM_FAILURE;
|
||||
SSMConnection *parent = arg->m_parent;
|
||||
|
||||
/* Parent has the nonce, so authenticate there. */
|
||||
if (parent &&
|
||||
SSM_IsAKindOf(&(parent->super), SSM_RESTYPE_CONTROL_CONNECTION))
|
||||
rv = SSMControlConnection_Authenticate(parent, nonce);
|
||||
|
||||
return rv;
|
||||
}
|
|
@ -83,6 +83,10 @@ typedef struct SSMDataConnection
|
|||
(usage depends on subclass) */
|
||||
} SSMDataConnection;
|
||||
|
||||
|
||||
PRBool AreConnectionsActive(void);
|
||||
|
||||
|
||||
SSMStatus SSMDataConnection_Create(void *arg, SSMControlConnection * conn,
|
||||
SSMResource **res);
|
||||
SSMStatus SSMDataConnection_Init(SSMDataConnection *conn,
|
||||
|
|
|
@ -30,8 +30,12 @@
|
|||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
#include "TArray.h"
|
||||
#include "TArrayIterator.h"
|
||||
//#include "TArray.h"
|
||||
//#include "TArrayIterator.h"
|
||||
|
||||
#include "nsError.h"
|
||||
#include "nsVoidArray.h"
|
||||
|
||||
#include "prthread.h"
|
||||
#include "prlog.h"
|
||||
#include "prmem.h"
|
||||
|
@ -43,31 +47,75 @@ typedef struct SSMThreadPrivateData
|
|||
PRUintn indx;
|
||||
} SSMThreadPrivateData;
|
||||
|
||||
TArray<PRThread *>* myThreads = NULL;
|
||||
PRUintn thdIndex = 0;
|
||||
|
||||
|
||||
static nsVoidArray* gThreadsList = NULL;
|
||||
static PRUintn gThreadIndex = 0;
|
||||
|
||||
|
||||
#ifdef DEBUG
|
||||
// just here to satisfy linkage in debug mode. nsTraceRefcnt is a class used for tracking
|
||||
// memory usage in debug builds. This is fragile, and a hack.
|
||||
class nsTraceRefcnt
|
||||
{
|
||||
|
||||
static NS_COM void LogCtor(void* aPtr, const char* aTypeName,
|
||||
PRUint32 aInstanceSize);
|
||||
|
||||
static NS_COM void LogDtor(void* aPtr, const char* aTypeName,
|
||||
PRUint32 aInstanceSize);
|
||||
|
||||
};
|
||||
|
||||
void nsTraceRefcnt::LogCtor(void* aPtr, const char* aTypeName,
|
||||
PRUint32 aInstanceSize)
|
||||
{}
|
||||
|
||||
void nsTraceRefcnt::LogDtor(void* aPtr, const char* aTypeName,
|
||||
PRUint32 aInstanceSize)
|
||||
{}
|
||||
#endif
|
||||
|
||||
|
||||
PRUintn GetThreadIndex()
|
||||
{
|
||||
return gThreadIndex;
|
||||
}
|
||||
|
||||
void
|
||||
SSM_MacDelistThread(void *priv)
|
||||
{
|
||||
// remove this lump from the list of active threads
|
||||
myThreads->Remove((PRThread *) priv);
|
||||
PR_ASSERT(gThreadsList);
|
||||
|
||||
PRBool removed = gThreadsList->RemoveElement(priv);
|
||||
PR_ASSERT(removed);
|
||||
|
||||
if (gThreadsList->Count() == 0)
|
||||
{
|
||||
delete gThreadsList;
|
||||
gThreadsList = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static PRBool InterruptThreadEnumerator(void* aElement, void *aData)
|
||||
{
|
||||
PRThread* theThread = (PRThread *)aElement;
|
||||
|
||||
nsresult rv = PR_Interrupt(theThread); // thread data dtor will deallocate (*priv)
|
||||
PR_ASSERT(rv == PR_SUCCESS);
|
||||
|
||||
return PR_TRUE; // continue
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
SSM_KillAllThreads(void)
|
||||
{
|
||||
int i;
|
||||
SSMThreadPrivateData *priv = NULL;
|
||||
PRStatus rv;
|
||||
|
||||
if (myThreads != nil) {
|
||||
TArrayIterator<PRThread*> iterator(*myThreads);
|
||||
PRThread *thd;
|
||||
while (iterator.Next(thd)) {
|
||||
rv = PR_Interrupt(thd); // thread data dtor will deallocate (*priv)
|
||||
PR_ASSERT(rv == PR_SUCCESS);
|
||||
}
|
||||
}
|
||||
if (gThreadsList)
|
||||
{
|
||||
gThreadsList->EnumerateForwards(InterruptThreadEnumerator, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
PRThread *
|
||||
|
@ -79,19 +127,20 @@ SSM_CreateAndRegisterThread(PRThreadType type,
|
|||
PRThreadState state,
|
||||
PRUint32 stackSize)
|
||||
{
|
||||
PRThread *thd;
|
||||
|
||||
if (!myThreads)
|
||||
if (!gThreadsList)
|
||||
{
|
||||
PR_NewThreadPrivateIndex(&thdIndex, SSM_MacDelistThread);
|
||||
myThreads = new TArray<PRThread*>;
|
||||
PR_NewThreadPrivateIndex(&gThreadIndex, SSM_MacDelistThread);
|
||||
gThreadsList = new nsVoidArray;
|
||||
}
|
||||
|
||||
thd = PR_CreateThread(type, start, arg, priority, scope, state, stackSize);
|
||||
if (thd)
|
||||
PRThread *newThread = PR_CreateThread(type, start, arg, priority, scope, state, stackSize);
|
||||
if (newThread)
|
||||
{
|
||||
/* Add this thread to our list of threads */
|
||||
myThreads->AddItem(thd);
|
||||
gThreadsList->AppendElement((void *)newThread);
|
||||
}
|
||||
|
||||
return newThread;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,278 +0,0 @@
|
|||
/*
|
||||
* The contents of this file are subject to the Mozilla 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/MPL/
|
||||
*
|
||||
* 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 the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
// ===========================================================================
|
||||
// CCompleteApp.cp ©1994-1998 Metrowerks Inc. All rights reserved.
|
||||
// ===========================================================================
|
||||
// This file contains the starter code for a complete PowerPlant project that
|
||||
// includes precompiled headers and both debug and release targets.
|
||||
|
||||
#include "macshell.h"
|
||||
|
||||
#include <LGrowZone.h>
|
||||
#include <LWindow.h>
|
||||
#include <PP_Messages.h>
|
||||
#include <PP_Resources.h>
|
||||
#include <PPobClasses.h>
|
||||
#include <UDrawingState.h>
|
||||
#include <UMemoryMgr.h>
|
||||
#include <URegistrar.h>
|
||||
#include "macstdlibextras.h"
|
||||
|
||||
#include "prthread.h"
|
||||
#include "prinit.h"
|
||||
#include "prlog.h"
|
||||
|
||||
#include "serv.h"
|
||||
|
||||
// put declarations for resource ids (ResIDTs) here
|
||||
|
||||
const PP_PowerPlant::ResIDT wind_SampleWindow = 128; // EXAMPLE, create a new window
|
||||
|
||||
//
|
||||
// NSPR repeater
|
||||
//
|
||||
|
||||
class CNSPRRepeater : public LPeriodical
|
||||
{
|
||||
public:
|
||||
CNSPRRepeater();
|
||||
virtual void SpendTime(const EventRecord& inEvent);
|
||||
};
|
||||
|
||||
CNSPRRepeater::CNSPRRepeater(void)
|
||||
: LPeriodical()
|
||||
{
|
||||
}
|
||||
|
||||
CNSPRRepeater *gNSPRRepeater;
|
||||
|
||||
PRBool gShouldQuit = PR_FALSE;
|
||||
|
||||
void
|
||||
CNSPRRepeater::SpendTime(const EventRecord& inEvent)
|
||||
{
|
||||
/*
|
||||
Can't just exit on the Mac, because otherwise the NSPR threads
|
||||
will keep spinning forever. We have to send the app a
|
||||
Quit command so that all the threads will shut down in an orderly
|
||||
way.
|
||||
|
||||
On top of that, NSPR threads can't send a Quit Apple Event, because
|
||||
that causes the threads to close improperly. So, we keep a flag and allow
|
||||
threads to raise it. We check for that flag here.
|
||||
*/
|
||||
|
||||
if (gShouldQuit)
|
||||
{
|
||||
if (gNSPRRepeater)
|
||||
gNSPRRepeater->StopIdling();
|
||||
// PR_Interrupt all threads (other than the primordial one)
|
||||
SSM_KillAllThreads();
|
||||
gTheApp->SendAEQuit(); // will cause this repeater to stop repeating
|
||||
}
|
||||
else
|
||||
PR_Sleep(PR_INTERVAL_NO_WAIT); // give time to NSPR threads
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
// ¥ Main Program
|
||||
// ===========================================================================
|
||||
|
||||
PRIntn MacPSMMain(PRIntn argc, char **argv);
|
||||
|
||||
int main()
|
||||
{
|
||||
char *fakeArgv[] = { NULL, NULL };
|
||||
#ifndef NDEBUG
|
||||
SetDebugThrow_(PP_PowerPlant::debugAction_Alert); // Set Debugging options
|
||||
SetDebugSignal_(PP_PowerPlant::debugAction_Alert);
|
||||
#endif
|
||||
|
||||
PP_PowerPlant::InitializeHeap(3); // Initialize Memory Manager
|
||||
// Parameter is number of Master Pointer
|
||||
// blocks to allocate
|
||||
|
||||
#ifdef DEBUG
|
||||
InitializeSIOUX(false); // prevent us from getting double menus, etc.
|
||||
#endif
|
||||
PP_PowerPlant::UQDGlobals::InitializeToolbox(&qd); // Initialize standard Toolbox managers
|
||||
|
||||
new PP_PowerPlant::LGrowZone(20000); // Install a GrowZone function to catch
|
||||
// low memory situations.
|
||||
PR_Initialize(MacPSMMain, 0, fakeArgv, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
CBasicApp *gTheApp;
|
||||
|
||||
PRIntn MacPSMMain(PRIntn argc, char **argv)
|
||||
{
|
||||
gNSPRRepeater = new CNSPRRepeater;
|
||||
PR_ASSERT(gNSPRRepeater != NULL);
|
||||
gNSPRRepeater->StartIdling();
|
||||
|
||||
CBasicApp theApp; // create instance of your application
|
||||
gTheApp = &theApp;
|
||||
|
||||
theApp.Run();
|
||||
return 0;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// ¥ CBasicApp
|
||||
// ---------------------------------------------------------------------------
|
||||
// Constructor
|
||||
|
||||
CBasicApp::CBasicApp()
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
PP_PowerPlant::RegisterAllPPClasses(); // Register functions to create core
|
||||
#else // PowerPlant classes
|
||||
RegisterClass_(PP_PowerPlant::LWindow);
|
||||
RegisterClass_(PP_PowerPlant::LCaption);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// ¥ ~CBasicApp
|
||||
// ---------------------------------------------------------------------------
|
||||
// Destructor
|
||||
|
||||
CBasicApp::~CBasicApp()
|
||||
{
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// ¥ StartUp
|
||||
// ---------------------------------------------------------------------------
|
||||
// This method lets you do something when the application starts up
|
||||
// without a document. For example, you could issue your own new command.
|
||||
|
||||
extern void RunMacPSM(void *);
|
||||
|
||||
void
|
||||
CBasicApp::StartUp()
|
||||
{
|
||||
// ObeyCommand(PP_PowerPlant::cmd_New, nil); // EXAMPLE, create a new window
|
||||
|
||||
/*
|
||||
The Unix/Win32 main function (which we call RunMacPSM) blocks on
|
||||
PR_Accept(), listening for control connections. Since we cannot
|
||||
block from the main thread, we have to spin a separate NSPR thread
|
||||
for RunMacPSM.
|
||||
*/
|
||||
SSM_CreateAndRegisterThread(PR_USER_THREAD,
|
||||
RunMacPSM,
|
||||
NULL,
|
||||
PR_PRIORITY_NORMAL,
|
||||
PR_LOCAL_THREAD,
|
||||
PR_UNJOINABLE_THREAD, 0);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// ¥ ObeyCommand
|
||||
// ---------------------------------------------------------------------------
|
||||
// This method lets the application respond to commands like Menu commands
|
||||
|
||||
Boolean
|
||||
CBasicApp::ObeyCommand(
|
||||
PP_PowerPlant::CommandT inCommand,
|
||||
void *ioParam)
|
||||
{
|
||||
Boolean cmdHandled = true;
|
||||
|
||||
switch (inCommand) {
|
||||
|
||||
// Handle command messages (defined in PP_Messages.h).
|
||||
case PP_PowerPlant::cmd_New:
|
||||
#if 0
|
||||
PP_PowerPlant::LWindow *theWindow =
|
||||
PP_PowerPlant::LWindow::CreateWindow(wind_SampleWindow, this);
|
||||
ThrowIfNil_(theWindow);
|
||||
|
||||
// LWindow is not initially visible in PPob resource
|
||||
theWindow->Show();
|
||||
break;
|
||||
#endif
|
||||
|
||||
case PP_PowerPlant::cmd_Quit:
|
||||
if (!gShouldQuit) // do this only if repeater hasn't done it for us
|
||||
{
|
||||
if (gNSPRRepeater)
|
||||
gNSPRRepeater->StopIdling();
|
||||
// PR_Interrupt all threads (other than the primordial one)
|
||||
SSM_KillAllThreads();
|
||||
}
|
||||
// fall through to default Quit behavior
|
||||
|
||||
// Any that you don't handle, such as cmd_About and cmd_Quit,
|
||||
// will be passed up to LApplication
|
||||
default:
|
||||
cmdHandled = PP_PowerPlant::LApplication::ObeyCommand(inCommand, ioParam);
|
||||
break;
|
||||
}
|
||||
|
||||
return cmdHandled;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// ¥ FindCommandStatus
|
||||
// ---------------------------------------------------------------------------
|
||||
// This method enables menu items.
|
||||
|
||||
void
|
||||
CBasicApp::FindCommandStatus(
|
||||
PP_PowerPlant::CommandT inCommand,
|
||||
Boolean &outEnabled,
|
||||
Boolean &outUsesMark,
|
||||
PP_PowerPlant::Char16 &outMark,
|
||||
Str255 outName)
|
||||
{
|
||||
|
||||
switch (inCommand) {
|
||||
|
||||
// Return menu item status according to command messages.
|
||||
case PP_PowerPlant::cmd_New:
|
||||
case PP_PowerPlant::cmd_Quit:
|
||||
outEnabled = true;
|
||||
break;
|
||||
|
||||
// Any that you don't handle, such as cmd_About and cmd_Quit,
|
||||
// will be passed up to LApplication
|
||||
default:
|
||||
PP_PowerPlant::LApplication::FindCommandStatus(inCommand, outEnabled,
|
||||
outUsesMark, outMark, outName);
|
||||
break;
|
||||
}
|
||||
}
|
|
@ -1,65 +0,0 @@
|
|||
/*
|
||||
* The contents of this file are subject to the Mozilla 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/MPL/
|
||||
*
|
||||
* 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 the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
// ===========================================================================
|
||||
// CCompleteApp.h ©1994-1998 Metrowerks Inc. All rights reserved.
|
||||
// ===========================================================================
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <PP_Prefix.h>
|
||||
#include <LApplication.h>
|
||||
|
||||
|
||||
class CBasicApp : public PP_PowerPlant::LApplication {
|
||||
|
||||
public:
|
||||
CBasicApp(); // constructor registers PPobs
|
||||
virtual ~CBasicApp(); // stub destructor
|
||||
|
||||
|
||||
// this overriding method handles application commands
|
||||
virtual Boolean ObeyCommand(PP_PowerPlant::CommandT inCommand, void* ioParam);
|
||||
|
||||
|
||||
// this overriding method returns the status of menu items
|
||||
virtual void FindCommandStatus(PP_PowerPlant::CommandT inCommand,
|
||||
Boolean &outEnabled, Boolean &outUsesMark,
|
||||
PP_PowerPlant::Char16 &outMark, Str255 outName);
|
||||
protected:
|
||||
|
||||
virtual void StartUp(); // override startup functions
|
||||
|
||||
};
|
||||
|
||||
|
||||
extern CBasicApp *gTheApp;
|
|
@ -156,23 +156,7 @@ static SSMStatus SSM_InstallSMIMEPolicy(void)
|
|||
*/
|
||||
SECStatus Utility_SetPolicy(long which, int policy)
|
||||
{
|
||||
if (which == POLICY_TYPE_INDEX) {
|
||||
switch (policy) {
|
||||
case SVRPLCYDomestic:
|
||||
policyType = ssmDomestic;
|
||||
break;
|
||||
case SVRPLCYExport:
|
||||
policyType = ssmExport;
|
||||
break;
|
||||
case SVRPLCYFrance:
|
||||
policyType = ssmFrance;
|
||||
break;
|
||||
default:
|
||||
/* This is an unknown policy type. */
|
||||
PR_ASSERT(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
policyType = ssmDomestic;
|
||||
return SECSuccess;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -231,7 +231,7 @@ ssm_DrainAndDestroyChildCollection(SSMCollection **coll)
|
|||
|
||||
/* Drain the collection. Don't block; presumably this is
|
||||
being done at destruction time. */
|
||||
while(SSM_Dequeue(v, SSM_PRIORITY_ANY, (void **) &conn, PR_FALSE) == PR_SUCCESS);
|
||||
while(SSM_Dequeue(v, SSM_PRIORITY_ANY, (void **) &conn, PR_FALSE) == PR_SUCCESS) {;}
|
||||
|
||||
/* Destroy the collection. */
|
||||
SSM_DestroyCollection(v);
|
||||
|
@ -282,13 +282,7 @@ SSM_AddLogSocket(PRFileDesc *fd)
|
|||
}
|
||||
|
||||
#ifdef XP_MAC
|
||||
/*
|
||||
Each thread, when registering itself using one of the two functions
|
||||
below, assigns itself as private data at index (thdIndex). This is
|
||||
necessary because when a thread exits, we want it to delete itself
|
||||
from the list of threads we need to kill at exit time.
|
||||
*/
|
||||
extern PRUintn thdIndex;
|
||||
#include "macglue.h"
|
||||
#endif
|
||||
|
||||
/* Called by a newly created thread, this associates a name with the thread. */
|
||||
|
@ -300,8 +294,17 @@ SSM_RegisterThread(char *threadName, SSMResource *ptr)
|
|||
char *value;
|
||||
|
||||
#ifdef XP_MAC
|
||||
if (thdIndex > 0)
|
||||
PR_SetThreadPrivate(thdIndex, PR_GetCurrentThread());
|
||||
/*
|
||||
Each thread, when registering itself using one of the two functions
|
||||
below, assigns itself as private data at index (thdIndex). This is
|
||||
necessary because when a thread exits, we want it to delete itself
|
||||
from the list of threads we need to kill at exit time.
|
||||
*/
|
||||
{
|
||||
PRUintn threadIndex = GetThreadIndex();
|
||||
if (threadIndex > 0)
|
||||
PR_SetThreadPrivate(threadIndex, PR_GetCurrentThread());
|
||||
}
|
||||
#endif
|
||||
|
||||
if (ptr)
|
||||
|
|
Загрузка…
Ссылка в новой задаче