add js to tree

git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@3693 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
Brian West committed 2006-12-18 15:53:47 +00:00
1 parent 855c7b9a77
commit fff98f6316
1137 files changed
+386873

No files matched your search

+18
View File
@@ -0,0 +1,18 @@
/MANIFEST/1.1/Thu Jun 4 22:51:07 1998//
/MacErrorHandling.h/3.4/Sun Apr 25 15:00:59 2004//
/macdll.c/3.12/Sun Apr 25 15:00:59 2004//
/macdll.h/1.5/Sun Apr 25 15:00:59 2004//
/macio.c/3.37/Sun Apr 25 15:00:59 2004//
/macio.h/1.4/Sun Apr 25 15:00:59 2004//
/macrng.c/1.7/Sun Apr 25 15:00:59 2004//
/macsocket.h/3.8/Sun Apr 25 15:00:59 2004//
/macsockotpt.c/3.42/Sun Apr 25 15:00:59 2004//
/macthr.c/3.22/Sun Apr 25 15:00:59 2004//
/mactime.c/3.8/Sun Apr 25 15:00:59 2004//
/mactime.h/1.4/Sun Apr 25 15:00:59 2004//
/mdcriticalregion.c/1.4/Sun Apr 25 15:00:59 2004//
/mdcriticalregion.h/1.3/Sun Apr 25 15:00:59 2004//
/mdmac.c/3.20/Mon Nov 7 22:39:01 2005//
/mdmac.h/1.4/Sun Apr 25 15:00:59 2004//
/prcpucfg.h/3.11/Sun Apr 25 15:00:59 2004//
D
@@ -0,0 +1 @@
mozilla/nsprpub/pr/src/md/mac
+1
View File
@@ -0,0 +1 @@
:pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot
+7
View File
@@ -0,0 +1,7 @@
#
# This is a list of local files which get copied to the mozilla:dist directory
#
MacErrorHandling.h
macsocket.h
prcpucfg.h
@@ -0,0 +1,668 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* 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 Portable Runtime (NSPR).
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998-2000
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/*********************************************************************
FILENAME
Exceptions.h
DESCRIPTION
A collection of routines and macros to handle assertions and
exceptions.
COPYRIGHT
Copyright © Apple Computer, Inc. 1989-1991
All rights reserved.
ROUTINES
EXTERNALS
dprintf
check_dprintf
checkpos_dprintf
MACROS
EXTERNALS
check
ncheck
check_action
ncheck_action
require
nrequire
require_action
nrequire_action
resume
MODIFICATION HISTORY
Nov 12 95 BKJ Moved to MetroWerks environment & the NSPR
NOTE
To keep code size down, use these routines and macros with the C
compiler option -b2 or -b3. This will eliminate duplicate strings
within a procedure.
*********************************************************************/
#ifndef __MACERRORHANDLING__
#define __MACERRORHANDLING__
/*********************************************************************
INCLUDES
*********************************************************************/
#include <Types.h>
/*<FF>*/
/*********************************************************************
CONSTANTS AND CONTROL
*********************************************************************/
/*
These defines are used to control the amount of information
displayed when an assertion fails. DEBUGOFF and WARN will run
silently. MIN will simply break into the debugger. ON will break
and display the assertion that failed and the exception (for
require statements). FULL will also display the source file name
and line number. SYM does a SysBreak and is usefull when using a
symbolic debugger like SourceBug or SADE. They should be set into
DEBUGLEVEL. The default LEVEL is OFF.
*/
#define DEBUGOFF 0
#define DEBUGWARN 1
#define DEBUGMIN 2
#define DEBUGON 3
#define DEBUGFULL 4
#define DEBUGSYM 6
#ifndef DEBUGLEVEL
#define DEBUGLEVEL DEBUGOFF
#endif DEBUGLEVEL
/*
resumeLabel is used to control the insertion of labels for use with
the resume macro. If you do not use the resume macro and you wish
to have multible exceptions per label then you can add the
following define to you source code.
*/
#define resumeLabel(exception) // Multiple exceptions per label
// #define resumeLabel(exception) resume_ ## exception: // Single exception per label
/*
traceon and debugon are used to test for options
*/
#define traceon ((DEBUGLEVEL > DEBUGWARN) && defined(TRACEON))
#define debugon (DEBUGLEVEL > DEBUGWARN)
/*
Add some macros for DEBUGMIN and DEBUGSYM to keep the size down.
*/
#define __DEBUGSMALL ((DEBUGLEVEL == DEBUGMIN) || \
(DEBUGLEVEL == DEBUGSYM))
#if DEBUGLEVEL == DEBUGMIN
#define __DebuggerBreak Debugger()
#elif DEBUGLEVEL == DEBUGSYM
#define __DebuggerBreak SysBreak()
#endif
/*<FF>*/
/*********************************************************************
MACRO
check(assertion)
DESCRIPTION
If debugging is on then check will test assertion and if it fails
break into the debugger. Otherwise check does nothing.
*********************************************************************/
#if __DEBUGSMALL
#define check(assertion) \
do { \
if (assertion) ; \
else __DebuggerBreak; \
} while (false)
#elif DEBUGLEVEL == DEBUGON
#define check(assertion) \
do { \
if (assertion) ; \
else { \
dprintf(notrace, "Assertion \"%s\" Failed", #assertion); \
} \
} while (false)
#elif DEBUGLEVEL == DEBUGFULL
#define check(assertion) \
do { \
if (assertion) ; \
else { \
dprintf(notrace, "Assertion \"%s\" Failed\n" \
"File: %s\n" \
"Line: %d", \
#assertion, __FILE__, __LINE__); \
} \
} while (false)
#else
#define check(assertion)
#endif
/*<FF>*/
/*********************************************************************
MACRO
ncheck(assertion)
DESCRIPTION
If debugging is on then ncheck will test !assertion and if it fails
break into the debugger. Otherwise ncheck does nothing.
*********************************************************************/
#if __DEBUGSMALL
#define ncheck(assertion) \
do { \
if (assertion) __DebuggerBreak; \
} while (false)
#elif DEBUGLEVEL == DEBUGON
#define ncheck(assertion) \
do { \
void* __privateAssertion = (void*)(assertion); \
\
if (__privateAssertion) { \
dprintf(notrace, "Assertion \"!(%s [= %#08X])\" Failed", \
#assertion, __privateAssertion); \
} \
} while (false)
#elif DEBUGLEVEL == DEBUGFULL
#define ncheck(assertion) \
do { \
void* __privateAssertion = (void*)(assertion); \
\
if (__privateAssertion) { \
dprintf(notrace, "Assertion \"!(%s [= %#08X])\" Failed\n" \
"File: %s\n" \
"Line: %d", \
#assertion, __privateAssertion, __FILE__, __LINE__); \
} \
} while (false)
#else
#define ncheck(assertion)
#endif
/*<FF>*/
/*********************************************************************
MACRO
check_action(assertion, action)
DESCRIPTION
If debugging is on then check_action will test assertion and if it
fails break into the debugger then execute action. Otherwise
check_action does nothing.
*********************************************************************/
#if __DEBUGSMALL
#define check_action(assertion, action) \
do { \
if (assertion) ; \
else { \
__DebuggerBreak; \
{ action } \
} while (false)
#elif DEBUGLEVEL == DEBUGON
#define check_action(assertion, action) \
do { \
if (assertion) ; \
else { \
dprintf(notrace, "Assertion \"%s\" Failed", #assertion); \
{ action } \
} \
} while (false)
#elif DEBUGLEVEL == DEBUGFULL
#define check_action(assertion, action) \
do { \
if (assertion) ; \
else { \
dprintf(notrace, "Assertion \"%s\" Failed\n" \
"File: %s\n" \
"Line: %d", \
#assertion, __FILE__, __LINE__); \
{ action } \
} \
} while (false)
#else
#define check_action(assertion, action)
#endif
/*<FF>*/
/**************************************************************************************
MACRO
ncheck_action(assertion, action)
DESCRIPTION
If debugging is on then ncheck_action will test !assertion and if
it fails break into the debugger then execute action. Otherwise
ncheck_action does nothing.
*********************************************************************/
#if __DEBUGSMALL
#define ncheck_action(assertion, action) \
do { \
if (assertion) { \
__DebuggerBreak; \
{ action } \
} \
} while (false)
#elif DEBUGLEVEL == DEBUGON
#define ncheck_action(assertion, action) \
do { \
void* __privateAssertion = (void*)(assertion); \
\
if (__privateAssertion) { \
dprintf(notrace, "Assertion \"!(%s [= %#08X])\" Failed", \
#assertion, __privateAssertion); \
{ action } \
} \
} while (false)
#elif DEBUGLEVEL == DEBUGFULL
#define ncheck_action(assertion, action) \
do { \
void* __privateAssertion = (void*)(assertion); \
\
if (__privateAssertion) { \
dprintf(notrace, "Assertion \"!(%s [= %#08X])\" Failed\n" \
"File: %s\n" \
"Line: %d", \
#assertion, __privateAssertion, __FILE__, __LINE__); \
{ action } \
} \
} while (false)
#else
#define ncheck_action(assertion, action)
#endif
/*<FF>*/
/*********************************************************************
MACRO
require(assertion, exception)
DESCRIPTION
require will test assertion and if it fails:
break into the debugger if debugging is on.
goto exception.
*********************************************************************/
#if __DEBUGSMALL
#define require(assertion, exception) \
do { \
if (assertion) ; \
else { \
__DebuggerBreak; \
goto exception; \
resumeLabel(exception); \
} \
} while (false)
#elif DEBUGLEVEL == DEBUGON
#define require(assertion, exception) \
do { \
if (assertion) ; \
else { \
dprintf(notrace, "Assertion \"%s\" Failed\n" \
"Exception \"%s\" Raised", \
#assertion, #exception); \
goto exception; \
resumeLabel(exception); \
} \
} while (false)
#elif DEBUGLEVEL == DEBUGFULL
#define require(assertion, exception) \
do { \
if (assertion) ; \
else { \
dprintf(notrace, "Assertion \"%s\" Failed\n" \
"Exception \"%s\" Raised\n" \
"File: %s\n" \
"Line: %d", \
#assertion, #exception, __FILE__, __LINE__); \
goto exception; \
resumeLabel(exception); \
} \
} while (false)
#else
#define require(assertion, exception) \
do { \
if (assertion) ; \
else { \
goto exception; \
resumeLabel(exception); \
} \
} while (false)
#endif
/*<FF>*/
/*********************************************************************
MACRO
nrequire(assertion, exception)
DESCRIPTION
nrequire will test !assertion and if it fails:
break into the debugger if debugging is on.
goto exception.
*********************************************************************/
#if __DEBUGSMALL
#define nrequire(assertion, exception) \
do { \
if (assertion) { \
DebugStr(); \
goto exception; \
resumeLabel(exception); \
} \
} while (false)
#elif DEBUGLEVEL == DEBUGON
#define nrequire(assertion, exception) \
do { \
void* __privateAssertion = (void*)(assertion); \
\
if (__privateAssertion) { \
dprintf(notrace, "Assertion \"!(%s [= %#08X])\" Failed\n" \
"Exception \"%s\" Raised", \
#assertion, __privateAssertion, #exception); \
goto exception; \
resumeLabel(exception); \
} \
} while (false)
#elif DEBUGLEVEL == DEBUGFULL
#define nrequire(assertion, exception) \
do { \
void* __privateAssertion = (void*)(assertion); \
\
if (__privateAssertion) { \
dprintf(notrace, "Assertion \"!(%s [= %#08X])\" Failed\n" \
"Exception \"%s\" Raised\n" \
"File: %s\n" \
"Line: %d", \
#assertion, __privateAssertion, #exception, __FILE__, \
__LINE__); \
goto exception; \
resumeLabel(exception); \
} \
} while (false)
#else
#define nrequire(assertion, exception) \
do { \
if (assertion) { \
goto exception; \
resumeLabel(exception); \
} \
} while (false)
#endif
/*<FF>*/
/*********************************************************************
MACRO
require_action(assertion, exception, action)
DESCRIPTION
require_action will test assertion and if it fails:
break into the debugger if debugging is on.
execute action.
goto exception.
*********************************************************************/
#if __DEBUGSMALL
#define require_action(assertion, exception, action) \
do { \
if (assertion) ; \
else { \
__DebuggerBreak; \
{ action } \
goto exception; \
resumeLabel(exception); \
} \
} while (false)
#elif DEBUGLEVEL == DEBUGON
#define require_action(assertion, exception, action) \
do { \
if (assertion) ; \
else { \
dprintf(notrace, "Assertion \"%s\" Failed\n" \
"Exception \"%s\" Raised", \
#assertion, #exception); \
{ action } \
goto exception; \
resumeLabel(exception); \
} \
} while (false)
#elif DEBUGLEVEL == DEBUGFULL
#define require_action(assertion, exception, action) \
do { \
if (assertion) ; \
else { \
dprintf(notrace, "Assertion \"%s\" Failed\n" \
"Exception \"%s\" Raised\n" \
"File: %s\n" \
"Line: %d", \
#assertion, #exception, __FILE__, __LINE__); \
{ action } \
goto exception; \
resumeLabel(exception); \
} \
} while (false)
#else
#define require_action(assertion, exception, action) \
do { \
if (assertion) ; \
else { \
{ action } \
goto exception; \
resumeLabel(exception); \
} \
} while (false)
#endif
/*<FF>*/
/*********************************************************************
MACRO
nrequire_action(assertion, exception, action)
DESCRIPTION
nrequire_action will test !assertion and if it fails:
break into the debugger if debugging is on.
execute action.
goto exception.
*********************************************************************/
#if __DEBUGSMALL
#define nrequire_action(assertion, exception, action) \
do { \
if (assertion) { \
__DebuggerBreak; \
{ action } \
goto exception; \
resumeLabel(exception); \
} \
} while (false)
#elif DEBUGLEVEL == DEBUGON
#define nrequire_action(assertion, exception, action) \
do { \
void* __privateAssertion = (void*)(assertion); \
\
if (__privateAssertion) { \
dprintf(notrace, "Assertion \"!(%s [= %#08X])\" Failed\n" \
"Exception \"%s\" Raised", \
#assertion, __privateAssertion, #exception); \
{ action } \
goto exception; \
resumeLabel(exception); \
} \
} while (false)
#elif DEBUGLEVEL == DEBUGFULL
#define nrequire_action(assertion, exception, action) \
do { \
void* __privateAssertion = (void*)(assertion); \
\
if (__privateAssertion) { \
dprintf(notrace, "Assertion \"!(%s [= %#08X])\" Failed\n" \
"Exception \"%s\" Raised\n" \
"File: %s\n" \
"Line: %d", \
#assertion, __privateAssertion, #exception, __FILE__, \
__LINE__); \
{ action } \
goto exception; \
resumeLabel(exception); \
} \
} while (false)
#else
#define nrequire_action(assertion, exception, action) \
do { \
if (assertion) { \
{ action } \
goto exception; \
resumeLabel(exception); \
} \
} while (false)
#endif
/*<FF>*/
/*********************************************************************
MACRO
resume(exception)
DESCRIPTION
resume will resume execution after the n/require/_action statement
specified by exception. Resume lables must be on (the default) in
order to use resume. If an action form of require was used then the
action will not be re-executed.
*********************************************************************/
#define resume(exception) \
do { \
goto resume_ ## exception; \
} while (false)
/*<FF>*/
/********************************************************************/
#endif
+587
View File
@@ -0,0 +1,587 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* 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 Portable Runtime (NSPR).
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998-2000
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include <string.h>
#include <Files.h>
#include <Errors.h>
#include <Folders.h>
#include <CodeFragments.h>
#include <Aliases.h>
#include <Resources.h>
#include "IterateDirectory.h" /* MoreFiles */
#include "MacErrorHandling.h"
#include "macdll.h"
#include "mdmac.h"
#include "macio.h"
#include "primpl.h"
#include "plstr.h"
/*
turds used to iterate through the directories looking
for the desired library.
*/
struct GetSharedLibraryFilterProcData
{
Boolean inRecursive;
StringPtr inName;
Boolean outFound;
CFragConnectionID outID;
Ptr outAddress;
OSErr outError;
};
typedef struct GetSharedLibraryFilterProcData GetSharedLibraryFilterProcData;
static pascal void
GetSharedLibraryFilterProc(const CInfoPBRec* const inCpb, Boolean* inWantQuit, void *inFilterData);
/*
NSGetSharedLibrary
Unfortunately CFM doesn't support user specified loader paths,
so we emulate the behavior. Effectively this is a GetSharedLibrary
where the loader path is user defined.
*/
OSErr
NSGetSharedLibrary(Str255 inLibName, CFragConnectionID* outID, Ptr* outMainAddr)
{
char* curLibPath;
char* freeCurLibPath;
OSErr tempErr;
Boolean recursive;
FSSpec curFolder;
GetSharedLibraryFilterProcData filterData;
char *endCurLibPath;
Boolean done;
filterData.outFound = false;
filterData.outID = (CFragConnectionID)(-1);
filterData.outAddress = NULL;
filterData.inName = inLibName;
freeCurLibPath = curLibPath = PR_GetLibraryPath();
if (curLibPath == NULL)
return (cfragNoLibraryErr);
tempErr = cfragNoLibraryErr;
do
{
endCurLibPath = PL_strchr(curLibPath, PR_PATH_SEPARATOR);
done = (endCurLibPath == NULL);
#if 0
// we overload the first character of a path if it's :
// then we want to recursively search that path
// see if path should be recursive
if (*curLibPath == ':')
{
// ':' is an illegal character in the name of a file
// if we start any path with this, we want to allow
// search recursively
curLibPath++;
recursive = true;
}
else
#endif
{
recursive = false;
}
if (!done)
*endCurLibPath = '\0'; // NULL terminate the string
// convert to FSSpec
tempErr = ConvertUnixPathToFSSpec(curLibPath, &curFolder);
// now look in this directory
if (noErr == tempErr)
{
filterData.inRecursive = recursive;
FSpIterateDirectory(&curFolder, recursive ? 0 : 1, &GetSharedLibraryFilterProc, &filterData);
if (filterData.outFound)
{
*outID = filterData.outID;
*outMainAddr = filterData.outAddress;
tempErr = noErr;
break;
}
else
{
tempErr = cfragNoLibraryErr;
}
}
curLibPath = endCurLibPath + 1; // skip to next path (past the '\0');
} while (!done);
free(freeCurLibPath);
return (tempErr);
}
static Boolean
LibInPefContainer(const FSSpec* inSpec, StringPtr inName, UInt32* outCodeOffset, UInt32* outCodeLength);
/*
GetSharedLibraryFilterProc
Callback to FSpIterateDirectory, finds a library with the name matching the
data in inFilterData (of type GetSharedLibraryFilterProcData). Forces a quit
when a match is found.
*/
static pascal void
GetSharedLibraryFilterProc(const CInfoPBRec* const inCpb, Boolean* inWantQuit, void *inFilterData)
{
GetSharedLibraryFilterProcData* pFilterData = (GetSharedLibraryFilterProcData*) inFilterData;
if ((inCpb->hFileInfo.ioFlAttrib & (1 << ioDirFlg)) == 0)
{
FSSpec fragSpec;
OSErr tempErr;
Str255 errName;
Boolean crap;
UInt32 codeOffset;
UInt32 codeLength;
// it's a file
// ¥ fix-me do we really want to allow all 'APPL's' for in which to find this library?
switch (inCpb->hFileInfo.ioFlFndrInfo.fdType)
{
case kCFragLibraryFileType:
case 'APPL':
tempErr = FSMakeFSSpec(inCpb->hFileInfo.ioVRefNum, inCpb->hFileInfo.ioFlParID, inCpb->hFileInfo.ioNamePtr, &fragSpec);
// this shouldn't fail
if (noErr != tempErr)
{
return;
}
// resolve an alias if this was one
tempErr = ResolveAliasFile(&fragSpec, true, &crap, &crap);
// if got here we have a shlb (or app-like shlb)
if (noErr != tempErr)
{
// probably couldn't resolve an alias
return;
}
break;
default:
return;
}
// see if this symbol is in this fragment
if (LibInPefContainer(&fragSpec, pFilterData->inName, &codeOffset, &codeLength))
tempErr = GetDiskFragment(&fragSpec, codeOffset, codeLength, fragSpec.name, kLoadCFrag, &pFilterData->outID, &pFilterData->outAddress, errName);
else
return;
// stop if we found a library by that name
if (noErr == tempErr)
{
*inWantQuit = true;
pFilterData->outFound = true;
pFilterData->outError = tempErr;
}
}
// FSpIterateDirectory will automagically call us for subsequent sub-dirs if necessary
}
/*
LibInPefContainer
Tell whether library inName is contained it the file pointed to by inSpec.
Return the codeOffset and codeLength information, for a subsequent
call to GetDiskFragment.
*/
static Boolean
LibInPefContainer(const FSSpec* inSpec, StringPtr inName, UInt32* outCodeOffset, UInt32* outCodeLength)
{
short refNum;
CFragResourceHandle hCfrg;
CFragResourceMember* pCurItem;
UInt32 curLibIndex;
Boolean found;
// asume we didn't find it
found = false;
// open the resource fork, if we can't bail
refNum = FSpOpenResFile(inSpec, fsRdPerm);
require(-1 != refNum, Exit);
// grab out the alias record, if it's not there bail
hCfrg = (CFragResourceHandle) Get1Resource(kCFragResourceType, kCFragResourceID);
require(NULL != hCfrg, CloseResourceAndExit);
HLock((Handle)hCfrg);
// get ptr to first item
pCurItem = &(*hCfrg)->firstMember;
for (curLibIndex = 0; curLibIndex < (*hCfrg)->memberCount; curLibIndex++)
{
// is this our library?
if ((pCurItem->name[0] == inName[0]) &&
(strncmp((char*) inName + 1, (char*) pCurItem->name + 1, PR_MIN(pCurItem->name[0], inName[0])) == 0))
{
*outCodeOffset = pCurItem->offset;
*outCodeLength = pCurItem->length;
found = true;
}
// skip to next one
pCurItem = (CFragResourceMember*) ((char*) pCurItem + pCurItem->memberSize);
}
HUnlock((Handle)hCfrg);
CloseResourceAndExit:
CloseResFile(refNum);
Exit:
return (found);
}
/*
NSFindSymbol
Workaround bug in CFM FindSymbol (in at least 7.5.5) where symbols with lengths
greater than 63 chars cause a "paramErr". We iterate through all symbols
in the library to find the desired symbol.
*/
OSErr
NSFindSymbol(CFragConnectionID inID, Str255 inSymName, Ptr* outMainAddr, CFragSymbolClass *outSymClass)
{
OSErr err;
if (inSymName[0] > 63)
{
/*
if there are greater than 63 characters in the
name, CFM FindSymbol fails, so let's iterate through all
of the symbols in the fragment and grab it
that way.
*/
long symbolCount;
Str255 curSymName;
long curIndex;
Boolean found;
found = false;
err = CountSymbols(inID, &symbolCount);
if (noErr == err)
{
/* now iterate through all the symbols in the library */
/* per DTS the indices apparently go 0 to n-1 */
for (curIndex = 0; (curIndex <= symbolCount - 1 && !found); curIndex++)
{
err = GetIndSymbol(inID, curIndex, curSymName, outMainAddr, outSymClass);
if (noErr == err && curSymName[0] == inSymName[0] && !strncmp((char*)curSymName + 1, (char*)inSymName + 1, curSymName[0]))
{
/* found our symbol */
found = true;
}
}
/* if we didn't find it set the error code so below it won't take this symbol */
if (!found)
err = cfragNoSymbolErr;
}
}
else
{
err = FindSymbol(inID, inSymName, outMainAddr, outSymClass);
}
return (err);
}
#pragma mark -
/*-----------------------------------------------------------------
GetNamedFragmentOffsets
Get the offsets into the data fork of the named fragment,
by reading the 'cfrg' resoruce.
-----------------------------------------------------------------*/
OSErr GetNamedFragmentOffsets(const FSSpec *fileSpec, const char* fragmentName,
UInt32 *outOffset, UInt32 *outLength)
{
CFragResourceHandle cFragHandle;
short fileRefNum;
OSErr err = noErr;
fileRefNum = FSpOpenResFile(fileSpec, fsRdPerm);
err = ResError();
if (err != noErr) return err;
cFragHandle = (CFragResourceHandle)Get1Resource(kCFragResourceType, kCFragResourceID);
if (!cFragHandle)
{
err = resNotFound;
goto done;
}
/* nothing here moves memory, so no need to lock the handle */
err = cfragNoLibraryErr; /* in case of failure */
*outOffset = 0;
*outLength = 0;
/* Now look for the named fragment */
if ((**cFragHandle).memberCount > 0)
{
CFragResourceMemberPtr memberPtr;
UInt16 i;
for ( i = 0, memberPtr = &(**cFragHandle).firstMember;
i < (**cFragHandle).memberCount;
i ++, memberPtr = (CFragResourceMemberPtr)((char *)memberPtr + memberPtr->memberSize))
{
char memberName[256];
UInt16 nameLen = PR_MIN(memberPtr->name[0], 255);
// avoid malloc here for speed
strncpy(memberName, (char *)&memberPtr->name[1], nameLen);
memberName[nameLen] = '\0';
// fragment names are case insensitive, so act like the system
if (PL_strcasecmp(memberName, fragmentName) == 0)
{
*outOffset = memberPtr->offset;
*outLength = memberPtr->length;
err = noErr;
break;
}
}
}
/* Resource handle will go away when the res fork is closed */
done:
CloseResFile(fileRefNum);
return err;
}
/*-----------------------------------------------------------------
GetIndexedFragmentOffsets
Get the offsets into the data fork of the indexed fragment,
by reading the 'cfrg' resoruce.
-----------------------------------------------------------------*/
OSErr GetIndexedFragmentOffsets(const FSSpec *fileSpec, UInt32 fragmentIndex,
UInt32 *outOffset, UInt32 *outLength, char **outFragmentName)
{
CFragResourceHandle cFragHandle;
short fileRefNum;
OSErr err = noErr;
fileRefNum = FSpOpenResFile(fileSpec, fsRdPerm);
err = ResError();
if (err != noErr) return err;
cFragHandle = (CFragResourceHandle)Get1Resource(kCFragResourceType, kCFragResourceID);
if (!cFragHandle)
{
err = resNotFound;
goto done;
}
err = cfragNoLibraryErr; /* in case of failure */
*outOffset = 0;
*outLength = 0;
*outFragmentName = NULL;
/* the CStrFromPStr mallocs, so might move memory */
HLock((Handle)cFragHandle);
/* Now look for the named fragment */
if ((**cFragHandle).memberCount > 0)
{
CFragResourceMemberPtr memberPtr;
UInt16 i;
for ( i = 0, memberPtr = &(**cFragHandle).firstMember;
i < (**cFragHandle).memberCount;
i ++, memberPtr = (CFragResourceMemberPtr)((char *)memberPtr + memberPtr->memberSize))
{
if (i == fragmentIndex)
{
char *fragmentStr;
CStrFromPStr(memberPtr->name, &fragmentStr);
if (!fragmentStr) /* test for allocation failure */
{
err = memFullErr;
break;
}
*outFragmentName = fragmentStr;
*outOffset = memberPtr->offset;
*outLength = memberPtr->length;
err = noErr;
break;
}
}
}
HUnlock((Handle)cFragHandle);
/* Resource handle will go away when the res fork is closed */
done:
CloseResFile(fileRefNum);
return err;
}
/*-----------------------------------------------------------------
NSLoadNamedFragment
Load the named fragment from the specified file. Aliases must
have been resolved by this point.
-----------------------------------------------------------------*/
OSErr NSLoadNamedFragment(const FSSpec *fileSpec, const char* fragmentName, CFragConnectionID *outConnectionID)
{
UInt32 fragOffset, fragLength;
short fragNameLength;
Ptr main;
Str255 fragName;
Str255 errName;
OSErr err;
err = GetNamedFragmentOffsets(fileSpec, fragmentName, &fragOffset, &fragLength);
if (err != noErr) return err;
// convert fragment name to pascal string
fragNameLength = strlen(fragmentName);
if (fragNameLength > 255)
fragNameLength = 255;
BlockMoveData(fragmentName, &fragName[1], fragNameLength);
fragName[0] = fragNameLength;
// Note that we pass the fragment name as the 4th param to GetDiskFragment.
// This value affects the ability of debuggers, and the Talkback system,
// to match code fragments with symbol files
err = GetDiskFragment(fileSpec, fragOffset, fragLength, fragName,
kLoadCFrag, outConnectionID, &main, errName);
return err;
}
/*-----------------------------------------------------------------
NSLoadIndexedFragment
Load the indexed fragment from the specified file. Aliases must
have been resolved by this point.
*outFragName is a malloc'd block containing the fragment name,
if returning noErr.
-----------------------------------------------------------------*/
OSErr NSLoadIndexedFragment(const FSSpec *fileSpec, PRUint32 fragmentIndex,
char** outFragName, CFragConnectionID *outConnectionID)
{
UInt32 fragOffset, fragLength;
char *fragNameBlock = NULL;
Ptr main;
Str255 fragName = "\p";
Str255 errName;
OSErr err;
*outFragName = NULL;
err = GetIndexedFragmentOffsets(fileSpec, fragmentIndex, &fragOffset, &fragLength, &fragNameBlock);
if (err != noErr) return err;
if (fragNameBlock)
{
UInt32 nameLen = strlen(fragNameBlock);
if (nameLen > 63)
nameLen = 63;
BlockMoveData(fragNameBlock, &fragName[1], nameLen);
fragName[0] = nameLen;
}
// Note that we pass the fragment name as the 4th param to GetDiskFragment.
// This value affects the ability of debuggers, and the Talkback system,
// to match code fragments with symbol files
err = GetDiskFragment(fileSpec, fragOffset, fragLength, fragName,
kLoadCFrag, outConnectionID, &main, errName);
if (err != noErr)
{
free(fragNameBlock);
return err;
}
*outFragName = fragNameBlock;
return noErr;
}
+57
View File
@@ -0,0 +1,57 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* 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 Portable Runtime (NSPR).
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998-2000
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef macdll_h__
#define macdll_h__
#include "prtypes.h"
OSErr GetNamedFragmentOffsets(const FSSpec *fileSpec, const char* fragmentName,
UInt32 *outOffset, UInt32 *outLength);
OSErr GetIndexedFragmentOffsets(const FSSpec *fileSpec, UInt32 fragmentIndex,
UInt32 *outOffset, UInt32 *outLength, char **outFragmentName);
OSErr NSLoadNamedFragment(const FSSpec *fileSpec, const char* fragmentName, CFragConnectionID *outConnectionID);
OSErr NSLoadIndexedFragment(const FSSpec *fileSpec, PRUint32 fragmentIndex,
char** outFragName, CFragConnectionID *outConnectionID);
OSErr NSGetSharedLibrary(Str255 inLibName, CFragConnectionID* outID, Ptr* outMainAddr);
OSErr NSFindSymbol(CFragConnectionID inID, Str255 inSymName,
Ptr* outMainAddr, CFragSymbolClass *outSymClass);
#endif /* macdll_h__ */
File diff suppressed because it is too large. Load diff
+51
View File
@@ -0,0 +1,51 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* 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 Portable Runtime (NSPR).
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998-2000
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef macio_h__
#define macio_h__
PR_BEGIN_EXTERN_C
OSErr ConvertUnixPathToMacPath(const char *, char **);
OSErr ConvertUnixPathToFSSpec(const char *unixPath, FSSpec *fileSpec);
PR_END_EXTERN_C
#endif /* macio_h__ */
+52
View File
@@ -0,0 +1,52 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* 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 Portable Runtime (NSPR).
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1999-2000
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/* XXX are all these headers required for a call to TickCount()? */
#include <Events.h>
#include <OSUtils.h>
#include <QDOffscreen.h>
#include <PPCToolbox.h>
#include <Processes.h>
#include <LowMem.h>
#include "primpl.h"
extern PRSize _PR_MD_GetRandomNoise( buf, size )
{
uint32 c = TickCount();
return _pr_CopyLowBits((void *)buf, size, &c, sizeof(c));
}
+238
View File
@@ -0,0 +1,238 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* 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 Portable Runtime (NSPR).
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998-2000
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef macksocket_h___
#define macksocket_h___
// macsock.h
// Interface visible to xp code
// C socket type definitions and routines
// from sys/socket.h
#include <Files.h>
#include <OpenTptInternet.h> // All the internet typedefs
#include <utime.h> // For timeval
/*
* sleep and delay conflict with the same in unistd.h from Metrowerks. OT
* defines them as
*
* extern pascal void OTDelay(UInt32 seconds);
* extern pascal void OTIdle(void);
*
* #define sleep(x) OTDelay(x)
* #define delay(x) OTDelay(x)
*/
#undef sleep
#undef delay
#pragma once
#include "prio.h"
struct sockaddr {
unsigned char sa_len; /* total length */
unsigned char sa_family; /* address family */
char sa_data[14]; /* actually longer; address value */
};
// from netinet/in.h
struct in_addr {
unsigned long s_addr;
};
struct sockaddr_in {
unsigned char sin_len;
unsigned char sin_family; // AF_INET
unsigned short sin_port;
struct in_addr sin_addr;
char sin_zero[8];
};
struct hostent {
char *h_name; /* official name of host */
char **h_aliases; /* alias list */
int h_addrtype; /* host address type */
int h_length; /* length of address */
char **h_addr_list; /* list of addresses from name server */
#define h_addr h_addr_list[0] /* address, for backward compatiblity */
};
// Necessary network defines, found by grepping unix headers when XP code would not compile
#define FIONBIO 1
#define SOCK_STREAM 1
#define SOCK_DGRAM 2
#define IPPROTO_TCP INET_TCP // Default TCP protocol
#define IPPROTO_UDP INET_UDP // Default UDP protocol
#define INADDR_ANY kOTAnyInetAddress
#define SOL_SOCKET XTI_GENERIC // Any type of socket
#define SO_REUSEADDR IP_REUSEADDR
#define SO_BROADCAST IP_BROADCAST
#define MSG_PEEK 0x2 // Just look at a message waiting, donÕt actually read it.
typedef unsigned long u_long;
/* ldap.h has its own definition of fd_set */
/* select support */
#if !defined(FD_SET)
#define NBBY 8
typedef long fd_mask;
#define NFDBITS (sizeof(fd_mask) * NBBY) /* bits per mask */
#ifndef howmany
#define howmany(x, y) (((x)+((y)-1))/(y))
#endif
#define FD_SETSIZE 64
typedef struct fd_set{
fd_mask fds_bits[howmany(FD_SETSIZE, NFDBITS)];
} fd_set;
#define FD_SET(n, p) ((p)->fds_bits[(n)/NFDBITS] |= (1 << ((n) % NFDBITS)))
#define FD_CLR(n, p) ((p)->fds_bits[(n)/NFDBITS] &= ~(1 << ((n) % NFDBITS)))
#define FD_ISSET(n, p) ((p)->fds_bits[(n)/NFDBITS] & (1 << ((n) % NFDBITS)))
#define FD_ZERO(p) memset (p, 0, sizeof(*(p)))
#endif /* !FD_SET */
#ifdef __cplusplus
extern "C" {
#endif
extern unsigned long inet_addr(const char *cp);
extern char *inet_ntoa(struct in_addr in);
inline unsigned long htonl(unsigned long hostlong) {return hostlong;}
inline unsigned long ntohl(unsigned long netlong) {return netlong;}
inline unsigned short ntohs(unsigned short netshort) {return netshort;}
inline unsigned short htons(unsigned short hostshort) {return hostshort;}
// UNIX look-alike routines
// They make sure that the arguments passed in are valid, and then
//
extern struct hostent *macsock_gethostbyaddr(const void *addr, int addrlen, int type);
extern int macsock_socket(int domain, int type, int protocol);
extern int macsock_ioctl(int sID, unsigned int request, void *value);
extern int macsock_connect(int sID, struct sockaddr *name, int namelen);
extern int macsock_write(int sID, const void *buffer, unsigned buflen);
extern int macsock_read(int sID, void *buf, unsigned nbyte);
extern int macsock_close(int sID);
extern int macsock_accept(int sID, struct sockaddr *addr, int *addrlen);
extern int macsock_bind(int sID, const struct sockaddr *name, int namelen);
extern int macsock_listen(int sID, int backlog);
extern int macsock_shutdown(int sID, int how);
extern int macsock_getpeername(int sID, struct sockaddr *name, int *namelen);
extern int macsock_getsockname(int sID, struct sockaddr *name, int *namelen);
extern int macsock_getsockopt(int sID, int level, int optname, void *optval,int *optlen);
extern int macsock_setsockopt(int sID, int level, int optname, const void *optval,int optlen);
extern int macsock_socketavailable(int sID, size_t *bytesAvailable);
extern int macsock_dup(int sID);
extern int macsock_send(int sID, const void *msg, int len, int flags);
extern int macsock_sendto(int sID, const void *msg, int len, int flags, struct sockaddr *toAddr, int toLen);
extern int macsock_recvfrom(int sID, void *buf, int len, int flags, struct sockaddr *from, int *fromLen);
extern int macsock_recv(int sID, void *buf, int len, int flags);
extern int select (int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);
#define macsock_gethostbyaddr PR_GetHostByAddr
#define macsock_socket PR_Socket
#define macsock_connect PR_Connect
#define macsock_write PR_Write
#define macsock_read PR_Read
#define macsock_close PR_Close
#define macsock_accept PR_Accept
#define macsock_bind PR_Bind
#define macsock_listen PR_Listen
#define macsock_shutdown PR_Shutdown
#define macsock_getpeername PR_GetPeerName
#define macsock_getsockname PR_GetSockName
#define macsock_socketavailable PR_SocketAvailable
#define macsock_send PR_Send
#define macsock_sendto PR_SendTo
#define macsock_recvfrom PR_RecvFrom
#define macsock_recv PR_Recv
#ifdef __cplusplus
}
#endif
//extern int errno;
/*
macsock_sendmsg
macsock_readv
macsock_writev
*/
/* New definitions that are not defined in macsock.h in macsock library */
struct protoent {
char *p_name; /* official protocol name */
char **p_aliases; /* alias list */
int p_proto; /* protocol # */
};
extern struct protoent *getprotobyname(const char * name);
extern struct protoent *getprotobynumber(int number);
extern int gethostname (char *name, int namelen);
extern struct hostent *gethostbyname(const char * name);
extern struct hostent *gethostbyaddr(const void *addr, int addrlen, int type);
#define INADDR_LOOPBACK 0x7F000001
#define SO_KEEPALIVE TCP_KEEPALIVE
#define SO_RCVBUF XTI_RCVBUF
#define SO_SNDBUF XTI_SNDBUF
#define SO_LINGER XTI_LINGER /* linger on close if data present */
#define IPPROTO_IP INET_IP
/* Get/Set sock opt until fixed in NSPR 2.0 */
struct linger {
int l_onoff; /* option on/off */
int l_linger; /* linger time */
};
struct ip_mreq {
struct in_addr imr_multiaddr; /* IP multicast address of group */
struct in_addr imr_interface; /* local IP address of interface */
};
#endif /* macksocket_h___ */
File diff suppressed because it is too large. Load diff
+721
View File
@@ -0,0 +1,721 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* 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 Portable Runtime (NSPR).
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998-2000
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "primpl.h"
#include <string.h>
#include <MacTypes.h>
#include <Timer.h>
#include <OSUtils.h>
#include <Math64.h>
#include <LowMem.h>
#include <Multiprocessing.h>
#include <Gestalt.h>
#include "mdcriticalregion.h"
TimerUPP gTimerCallbackUPP = NULL;
PRThread * gPrimaryThread = NULL;
ProcessSerialNumber gApplicationProcess;
PR_IMPLEMENT(PRThread *) PR_GetPrimaryThread()
{
return gPrimaryThread;
}
//##############################################################################
//##############################################################################
#pragma mark -
#pragma mark CREATING MACINTOSH THREAD STACKS
#if defined(GC_LEAK_DETECTOR)
extern void* GC_malloc_atomic(PRUint32 size);
#endif
/*
** Allocate a new memory segment. We allocate it from our figment heap. Currently,
** it is being used for per thread stack space.
**
** Return the segment's access rights and size. vaddr is used on Unix platforms to
** map an existing address for the segment.
*/
PRStatus _MD_AllocSegment(PRSegment *seg, PRUint32 size, void *vaddr)
{
PR_ASSERT(seg != 0);
PR_ASSERT(size != 0);
PR_ASSERT(vaddr == 0);
/*
** Take the actual memory for the segment out of our Figment heap.
*/
#if defined(GC_LEAK_DETECTOR)
seg->vaddr = (char *)GC_malloc_atomic(size);
#else
seg->vaddr = (char *)malloc(size);
#endif
if (seg->vaddr == NULL) {
#if DEBUG
DebugStr("\p_MD_AllocSegment failed.");
#endif
return PR_FAILURE;
}
seg->size = size;
return PR_SUCCESS;
}
/*
** Free previously allocated memory segment.
*/
void _MD_FreeSegment(PRSegment *seg)
{
PR_ASSERT((seg->flags & _PR_SEG_VM) == 0);
if (seg->vaddr != NULL)
free(seg->vaddr);
}
/*
** The thread's stack has been allocated and its fields are already properly filled
** in by PR. Perform any debugging related initialization here.
**
** Put a recognizable pattern so that we can find it from Macsbug.
** Put a cookie at the top of the stack so that we can find it from Macsbug.
*/
void _MD_InitStack(PRThreadStack *ts, int redZoneBytes)
{
#pragma unused (redZoneBytes)
#if DEVELOPER_DEBUG
// Put a cookie at the top of the stack so that we can find
// it from Macsbug.
memset(ts->allocBase, 0xDC, ts->stackSize);
((UInt32 *)ts->stackTop)[-1] = 0xBEEFCAFE;
((UInt32 *)ts->stackTop)[-2] = (UInt32)gPrimaryThread;
((UInt32 *)ts->stackTop)[-3] = (UInt32)(ts);
((UInt32 *)ts->stackBottom)[0] = 0xCAFEBEEF;
#else
#pragma unused (ts)
#endif
}
extern void _MD_ClearStack(PRThreadStack *ts)
{
#if DEVELOPER_DEBUG
// Clear out our cookies.
memset(ts->allocBase, 0xEF, ts->allocSize);
((UInt32 *)ts->stackTop)[-1] = 0;
((UInt32 *)ts->stackTop)[-2] = 0;
((UInt32 *)ts->stackTop)[-3] = 0;
((UInt32 *)ts->stackBottom)[0] = 0;
#else
#pragma unused (ts)
#endif
}
//##############################################################################
//##############################################################################
#pragma mark -
#pragma mark TIME MANAGER-BASED CLOCK
// On Mac OS X, it's possible for the application to spend lots of time
// in WaitNextEvent, yielding to other applications. Since NSPR threads are
// cooperative here, this means that NSPR threads will also get very little
// time to run. To kick ourselves out of a WaitNextEvent call when we have
// determined that it's time to schedule another thread, the Timer Task
// (which fires every 8ms, even when other apps have the CPU) calls WakeUpProcess.
// We only want to do this on Mac OS X; the gTimeManagerTaskDoesWUP variable
// indicates when we're running on that OS.
//
// Note that the TimerCallback makes use of gApplicationProcess. We need to
// have set this up before the first possible run of the timer task; we do
// so in _MD_EarlyInit().
static Boolean gTimeManagerTaskDoesWUP;
static TMTask gTimeManagerTaskElem;
extern void _MD_IOInterrupt(void);
_PRInterruptTable _pr_interruptTable[] = {
{ "clock", _PR_MISSED_CLOCK, _PR_ClockInterrupt, },
{ "i/o", _PR_MISSED_IO, _MD_IOInterrupt, },
{ 0 }
};
#define kMacTimerInMiliSecs 8L
pascal void TimerCallback(TMTaskPtr tmTaskPtr)
{
_PRCPU *cpu = _PR_MD_CURRENT_CPU();
PRIntn is;
if (_PR_MD_GET_INTSOFF()) {
cpu->u.missed[cpu->where] |= _PR_MISSED_CLOCK;
PrimeTime((QElemPtr)tmTaskPtr, kMacTimerInMiliSecs);
return;
}
_PR_INTSOFF(is);
// And tell nspr that a clock interrupt occured.
_PR_ClockInterrupt();
if ((_PR_RUNQREADYMASK(cpu)) >> ((_PR_MD_CURRENT_THREAD()->priority))) {
if (gTimeManagerTaskDoesWUP) {
// We only want to call WakeUpProcess if we know that NSPR has managed to switch threads
// since the last call, otherwise we end up spewing out WakeUpProcess() calls while the
// application is blocking somewhere. This can interfere with events loops other than
// our own (see bug 158927).
if (UnsignedWideToUInt64(cpu->md.lastThreadSwitch) > UnsignedWideToUInt64(cpu->md.lastWakeUpProcess))
{
WakeUpProcess(&gApplicationProcess);
cpu->md.lastWakeUpProcess = UpTime();
}
}
_PR_SET_RESCHED_FLAG();
}
_PR_FAST_INTSON(is);
// Reset the clock timer so that we fire again.
PrimeTime((QElemPtr)tmTaskPtr, kMacTimerInMiliSecs);
}
void _MD_StartInterrupts(void)
{
gPrimaryThread = _PR_MD_CURRENT_THREAD();
gTimeManagerTaskDoesWUP = RunningOnOSX();
if ( !gTimerCallbackUPP )
gTimerCallbackUPP = NewTimerUPP(TimerCallback);
// Fill in the Time Manager queue element
gTimeManagerTaskElem.tmAddr = (TimerUPP)gTimerCallbackUPP;
gTimeManagerTaskElem.tmCount = 0;
gTimeManagerTaskElem.tmWakeUp = 0;
gTimeManagerTaskElem.tmReserved = 0;
// Make sure that our time manager task is ready to go.
InsTime((QElemPtr)&gTimeManagerTaskElem);
PrimeTime((QElemPtr)&gTimeManagerTaskElem, kMacTimerInMiliSecs);
}
void _MD_StopInterrupts(void)
{
if (gTimeManagerTaskElem.tmAddr != NULL) {
RmvTime((QElemPtr)&gTimeManagerTaskElem);
gTimeManagerTaskElem.tmAddr = NULL;
}
}
#define MAX_PAUSE_TIMEOUT_MS 500
void _MD_PauseCPU(PRIntervalTime timeout)
{
if (timeout != PR_INTERVAL_NO_WAIT)
{
// There is a race condition entering the critical section
// in AsyncIOCompletion (and probably elsewhere) that can
// causes deadlock for the duration of this timeout. To
// work around this, use a max 500ms timeout for now.
// See bug 99561 for details.
if (PR_IntervalToMilliseconds(timeout) > MAX_PAUSE_TIMEOUT_MS)
timeout = PR_MillisecondsToInterval(MAX_PAUSE_TIMEOUT_MS);
WaitOnIdleSemaphore(timeout);
(void) _MD_IOInterrupt();
}
}
void _MD_InitRunningCPU(_PRCPU* cpu)
{
cpu->md.trackScheduling = RunningOnOSX();
if (cpu->md.trackScheduling) {
AbsoluteTime zeroTime = {0, 0};
cpu->md.lastThreadSwitch = UpTime();
cpu->md.lastWakeUpProcess = zeroTime;
}
}
//##############################################################################
//##############################################################################
#pragma mark -
#pragma mark THREAD SUPPORT FUNCTIONS
#include <OpenTransport.h> /* for error codes */
PRStatus _MD_InitThread(PRThread *thread)
{
thread->md.asyncIOLock = PR_NewLock();
PR_ASSERT(thread->md.asyncIOLock != NULL);
thread->md.asyncIOCVar = PR_NewCondVar(thread->md.asyncIOLock);
PR_ASSERT(thread->md.asyncIOCVar != NULL);
if (thread->md.asyncIOLock == NULL || thread->md.asyncIOCVar == NULL)
return PR_FAILURE;
else
return PR_SUCCESS;
}
PRStatus _MD_wait(PRThread *thread, PRIntervalTime timeout)
{
#pragma unused (timeout)
_MD_SWITCH_CONTEXT(thread);
return PR_SUCCESS;
}
void WaitOnThisThread(PRThread *thread, PRIntervalTime timeout)
{
intn is;
PRIntervalTime timein = PR_IntervalNow();
PRStatus status = PR_SUCCESS;
// Turn interrupts off to avoid a race over lock ownership with the callback
// (which can fire at any time). Interrupts may stay off until we leave
// this function, or another NSPR thread turns them back on. They certainly
// stay off until PR_WaitCondVar() relinquishes the asyncIOLock lock, which
// is what we care about.
_PR_INTSOFF(is);
PR_Lock(thread->md.asyncIOLock);
if (timeout == PR_INTERVAL_NO_TIMEOUT) {
while ((thread->io_pending) && (status == PR_SUCCESS))
status = PR_WaitCondVar(thread->md.asyncIOCVar, PR_INTERVAL_NO_TIMEOUT);
} else {
while ((thread->io_pending) && ((PRIntervalTime)(PR_IntervalNow() - timein) < timeout) && (status == PR_SUCCESS))
status = PR_WaitCondVar(thread->md.asyncIOCVar, timeout);
}
if ((status == PR_FAILURE) && (PR_GetError() == PR_PENDING_INTERRUPT_ERROR)) {
thread->md.osErrCode = kEINTRErr;
} else if (thread->io_pending) {
thread->md.osErrCode = kETIMEDOUTErr;
PR_SetError(PR_IO_TIMEOUT_ERROR, kETIMEDOUTErr);
}
thread->io_pending = PR_FALSE;
PR_Unlock(thread->md.asyncIOLock);
_PR_FAST_INTSON(is);
}
void DoneWaitingOnThisThread(PRThread *thread)
{
intn is;
PR_ASSERT(thread->md.asyncIOLock->owner == NULL);
// DoneWaitingOnThisThread() is called from OT notifiers and async file I/O
// callbacks that can run at "interrupt" time (Classic Mac OS) or on pthreads
// that may run concurrently with the main threads (Mac OS X). They can thus
// be called when any NSPR thread is running, or even while NSPR is in a
// thread context switch. It is therefore vital that we can guarantee to
// be able to get the asyncIOLock without blocking (thus avoiding code
// that makes assumptions about the current NSPR thread etc). To achieve
// this, we use NSPR interrrupts as a semaphore on the lock; all code
// that grabs the lock also disables interrupts for the time the lock
// is held. Callers of DoneWaitingOnThisThread() thus have to check whether
// interrupts are already off, and, if so, simply set the missed_IO flag on
// the CPU rather than calling this function.
_PR_INTSOFF(is);
PR_Lock(thread->md.asyncIOLock);
thread->io_pending = PR_FALSE;
/* let the waiting thread know that async IO completed */
PR_NotifyCondVar(thread->md.asyncIOCVar);
PR_Unlock(thread->md.asyncIOLock);
_PR_FAST_INTSON(is);
}
PR_IMPLEMENT(void) PR_Mac_WaitForAsyncNotify(PRIntervalTime timeout)
{
intn is;
PRIntervalTime timein = PR_IntervalNow();
PRStatus status = PR_SUCCESS;
PRThread *thread = _PR_MD_CURRENT_THREAD();
// See commments in WaitOnThisThread()
_PR_INTSOFF(is);
PR_Lock(thread->md.asyncIOLock);
if (timeout == PR_INTERVAL_NO_TIMEOUT) {
while ((!thread->md.asyncNotifyPending) && (status == PR_SUCCESS))
status = PR_WaitCondVar(thread->md.asyncIOCVar, PR_INTERVAL_NO_TIMEOUT);
} else {
while ((!thread->md.asyncNotifyPending) && ((PRIntervalTime)(PR_IntervalNow() - timein) < timeout) && (status == PR_SUCCESS))
status = PR_WaitCondVar(thread->md.asyncIOCVar, timeout);
}
if ((status == PR_FAILURE) && (PR_GetError() == PR_PENDING_INTERRUPT_ERROR)) {
thread->md.osErrCode = kEINTRErr;
} else if (!thread->md.asyncNotifyPending) {
thread->md.osErrCode = kETIMEDOUTErr;
PR_SetError(PR_IO_TIMEOUT_ERROR, kETIMEDOUTErr);
}
thread->md.asyncNotifyPending = PR_FALSE;
PR_Unlock(thread->md.asyncIOLock);
_PR_FAST_INTSON(is);
}
void AsyncNotify(PRThread *thread)
{
intn is;
PR_ASSERT(thread->md.asyncIOLock->owner == NULL);
// See commments in DoneWaitingOnThisThread()
_PR_INTSOFF(is);
PR_Lock(thread->md.asyncIOLock);
thread->md.asyncNotifyPending = PR_TRUE;
/* let the waiting thread know that async IO completed */
PR_NotifyCondVar(thread->md.asyncIOCVar);
PR_Unlock(thread->md.asyncIOLock);
_PR_FAST_INTSON(is);
}
PR_IMPLEMENT(void) PR_Mac_PostAsyncNotify(PRThread *thread)
{
_PRCPU * cpu = _PR_MD_CURRENT_CPU();
if (_PR_MD_GET_INTSOFF()) {
thread->md.missedAsyncNotify = PR_TRUE;
cpu->u.missed[cpu->where] |= _PR_MISSED_IO;
} else {
AsyncNotify(thread);
}
}
//##############################################################################
//##############################################################################
#pragma mark -
#pragma mark PROCESS SUPPORT FUNCTIONS
PRProcess * _MD_CreateProcess(
const char *path,
char *const *argv,
char *const *envp,
const PRProcessAttr *attr)
{
#pragma unused (path, argv, envp, attr)
PR_SetError(PR_NOT_IMPLEMENTED_ERROR, unimpErr);
return NULL;
}
PRStatus _MD_DetachProcess(PRProcess *process)
{
#pragma unused (process)
PR_SetError(PR_NOT_IMPLEMENTED_ERROR, unimpErr);
return PR_FAILURE;
}
PRStatus _MD_WaitProcess(PRProcess *process, PRInt32 *exitCode)
{
#pragma unused (process, exitCode)
PR_SetError(PR_NOT_IMPLEMENTED_ERROR, unimpErr);
return PR_FAILURE;
}
PRStatus _MD_KillProcess(PRProcess *process)
{
#pragma unused (process)
PR_SetError(PR_NOT_IMPLEMENTED_ERROR, unimpErr);
return PR_FAILURE;
}
//##############################################################################
//##############################################################################
#pragma mark -
#pragma mark ATOMIC OPERATIONS
#ifdef _PR_HAVE_ATOMIC_OPS
PRInt32
_MD_AtomicSet(PRInt32 *val, PRInt32 newval)
{
PRInt32 rv;
do {
rv = *val;
} while (!OTCompareAndSwap32(rv, newval, (UInt32*)val));
return rv;
}
#endif // _PR_HAVE_ATOMIC_OPS
//##############################################################################
//##############################################################################
#pragma mark -
#pragma mark INTERRUPT SUPPORT
#if TARGET_CARBON
/*
This critical region support is required for Mac NSPR to work correctly on dual CPU
machines on Mac OS X. This note explains why.
NSPR uses a timer task, and has callbacks for async file I/O and Open Transport
whose runtime behaviour differs depending on environment. On "Classic" Mac OS
these run at "interrupt" time (OS-level interrupts, that is, not NSPR interrupts),
and can thus preempt other code, but they always run to completion.
On Mac OS X, these are all emulated using MP tasks, which sit atop pthreads. Thus,
they can be preempted at any time (and not necessarily run to completion), and can
also run *concurrently* with eachother, and with application code, on multiple
CPU machines. Note that all NSPR threads are emulated, and all run on the main
application MP task.
We thus have to use MP critical sections to protect data that is shared between
the various callbacks and the main MP thread. It so happens that NSPR has this
concept of software interrupts, and making interrupt-off times be critical
sections works.
*/
/*
Whether to use critical regions. True if running on Mac OS X and later
*/
PRBool gUseCriticalRegions;
/*
Count of the number of times we've entered the critical region.
We need this because ENTER_CRITICAL_REGION() will *not* block when
called from different NSPR threads (which all run on one MP thread),
and we need to ensure that when code turns interrupts back on (by
settings _pr_intsOff to 0) we exit the critical section enough times
to leave it.
*/
PRInt32 gCriticalRegionEntryCount;
void _MD_SetIntsOff(PRInt32 ints)
{
ENTER_CRITICAL_REGION();
gCriticalRegionEntryCount ++;
_pr_intsOff = ints;
if (!ints)
{
PRInt32 i = gCriticalRegionEntryCount;
gCriticalRegionEntryCount = 0;
for ( ;i > 0; i --) {
LEAVE_CRITICAL_REGION();
}
}
}
#endif /* TARGET_CARBON */
//##############################################################################
//##############################################################################
#pragma mark -
#pragma mark CRITICAL REGION SUPPORT
static PRBool RunningOnOSX()
{
long systemVersion;
OSErr err = Gestalt(gestaltSystemVersion, &systemVersion);
return (err == noErr) && (systemVersion >= 0x00001000);
}
#if MAC_CRITICAL_REGIONS
MDCriticalRegionID gCriticalRegion;
void InitCriticalRegion()
{
OSStatus err;
// we only need to do critical region stuff on Mac OS X
gUseCriticalRegions = RunningOnOSX();
if (!gUseCriticalRegions) return;
err = MD_CriticalRegionCreate(&gCriticalRegion);
PR_ASSERT(err == noErr);
}
void TermCriticalRegion()
{
OSStatus err;
if (!gUseCriticalRegions) return;
err = MD_CriticalRegionDelete(gCriticalRegion);
PR_ASSERT(err == noErr);
}
void EnterCritialRegion()
{
OSStatus err;
if (!gUseCriticalRegions) return;
PR_ASSERT(gCriticalRegion != kInvalidID);
/* Change to a non-infinite timeout for debugging purposes */
err = MD_CriticalRegionEnter(gCriticalRegion, kDurationForever /* 10000 * kDurationMillisecond */ );
PR_ASSERT(err == noErr);
}
void LeaveCritialRegion()
{
OSStatus err;
if (!gUseCriticalRegions) return;
PR_ASSERT(gCriticalRegion != kInvalidID);
err = MD_CriticalRegionExit(gCriticalRegion);
PR_ASSERT(err == noErr);
}
#endif // MAC_CRITICAL_REGIONS
//##############################################################################
//##############################################################################
#pragma mark -
#pragma mark IDLE SEMAPHORE SUPPORT
/*
Since the WaitNextEvent() in _MD_PauseCPU() is causing all sorts of
headache under Mac OS X we're going to switch to MPWaitOnSemaphore()
which should do what we want
*/
#if TARGET_CARBON
PRBool gUseIdleSemaphore = PR_FALSE;
MPSemaphoreID gIdleSemaphore = NULL;
#endif
void InitIdleSemaphore()
{
// we only need to do idle semaphore stuff on Mac OS X
#if TARGET_CARBON
gUseIdleSemaphore = RunningOnOSX();
if (gUseIdleSemaphore)
{
OSStatus err = MPCreateSemaphore(1 /* max value */, 0 /* initial value */, &gIdleSemaphore);
PR_ASSERT(err == noErr);
}
#endif
}
void TermIdleSemaphore()
{
#if TARGET_CARBON
if (gUseIdleSemaphore)
{
OSStatus err = MPDeleteSemaphore(gIdleSemaphore);
PR_ASSERT(err == noErr);
gUseIdleSemaphore = NULL;
}
#endif
}
void WaitOnIdleSemaphore(PRIntervalTime timeout)
{
#if TARGET_CARBON
if (gUseIdleSemaphore)
{
OSStatus err = MPWaitOnSemaphore(gIdleSemaphore, kDurationMillisecond * PR_IntervalToMilliseconds(timeout));
PR_ASSERT(err == noErr);
}
else
#endif
{
EventRecord theEvent;
/*
** Calling WaitNextEvent() here is suboptimal. This routine should
** pause the process until IO or the timeout occur, yielding time to
** other processes on operating systems that require this (Mac OS classic).
** WaitNextEvent() may incur too much latency, and has other problems,
** such as the potential to drop suspend/resume events.
*/
(void)WaitNextEvent(nullEvent, &theEvent, 1, NULL);
}
}
void SignalIdleSemaphore()
{
#if TARGET_CARBON
if (gUseIdleSemaphore)
{
// often we won't be waiting on the semaphore here, so ignore any errors
(void)MPSignalSemaphore(gIdleSemaphore);
}
else
#endif
{
WakeUpProcess(&gApplicationProcess);
}
}
+253
View File
@@ -0,0 +1,253 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* 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 Portable Runtime (NSPR).
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998-2000
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include <OSUtils.h>
#include <Timer.h>
#include "primpl.h"
#include "mactime.h"
unsigned long gJanuaryFirst1970Seconds;
/*
* The geographic location and time zone information of a Mac
* are stored in extended parameter RAM. The ReadLocation
* produdure uses the geographic location record, MachineLocation,
* to read the geographic location and time zone information in
* extended parameter RAM.
*
* Because serial port and SLIP conflict with ReadXPram calls,
* we cache the call here.
*
* Caveat: this caching will give the wrong result if a session
* extend across the DST changeover time.
*/
static void MyReadLocation(MachineLocation *loc)
{
static MachineLocation storedLoc;
static Boolean didReadLocation = false;
if (!didReadLocation) {
ReadLocation(&storedLoc);
didReadLocation = true;
}
*loc = storedLoc;
}
static long GMTDelta(void)
{
MachineLocation loc;
long gmtDelta;
MyReadLocation(&loc);
gmtDelta = loc.u.gmtDelta & 0x00ffffff;
if (gmtDelta & 0x00800000) { /* test sign extend bit */
gmtDelta |= 0xff000000;
}
return gmtDelta;
}
void MacintoshInitializeTime(void)
{
/*
* The NSPR epoch is midnight, Jan. 1, 1970 GMT.
*
* At midnight Jan. 1, 1970 GMT, the local time was
* midnight Jan. 1, 1970 + GMTDelta().
*
* Midnight Jan. 1, 1970 is 86400 * (365 * (1970 - 1904) + 17)
* = 2082844800 seconds since the Mac epoch.
* (There were 17 leap years from 1904 to 1970.)
*
* So the NSPR epoch is 2082844800 + GMTDelta() seconds since
* the Mac epoch. Whew! :-)
*/
gJanuaryFirst1970Seconds = 2082844800 + GMTDelta();
}
/*
*-----------------------------------------------------------------------
*
* PR_Now --
*
* Returns the current time in microseconds since the epoch.
* The epoch is midnight January 1, 1970 GMT.
* The implementation is machine dependent. This is the Mac
* Implementation.
* Cf. time_t time(time_t *tp)
*
*-----------------------------------------------------------------------
*/
PRTime PR_Now(void)
{
unsigned long currentTime; /* unsigned 32-bit integer, ranging
from midnight Jan. 1, 1904 to
6:28:15 AM Feb. 6, 2040 */
PRTime retVal;
int64 usecPerSec;
/*
* Get the current time expressed as the number of seconds
* elapsed since the Mac epoch, midnight, Jan. 1, 1904 (local time).
* On a Mac, current time accuracy is up to a second.
*/
GetDateTime(&currentTime);
/*
* Express the current time relative to the NSPR epoch,
* midnight, Jan. 1, 1970 GMT.
*
* At midnight Jan. 1, 1970 GMT, the local time was
* midnight Jan. 1, 1970 + GMTDelta().
*
* Midnight Jan. 1, 1970 is 86400 * (365 * (1970 - 1904) + 17)
* = 2082844800 seconds since the Mac epoch.
* (There were 17 leap years from 1904 to 1970.)
*
* So the NSPR epoch is 2082844800 + GMTDelta() seconds since
* the Mac epoch. Whew! :-)
*/
currentTime = currentTime - 2082844800 - GMTDelta();
/* Convert seconds to microseconds */
LL_I2L(usecPerSec, PR_USEC_PER_SEC);
LL_I2L(retVal, currentTime);
LL_MUL(retVal, retVal, usecPerSec);
return retVal;
}
/*
*-------------------------------------------------------------------------
*
* PR_LocalTimeParameters --
*
* returns the time parameters for the local time zone
*
* This is the machine-dependent implementation for Mac.
*
* Caveat: On a Mac, we only know the GMT and DST offsets for
* the current time, not for the time in question.
* Mac has no support for DST handling.
* DST changeover is all manually set by the user.
*
*-------------------------------------------------------------------------
*/
PRTimeParameters PR_LocalTimeParameters(const PRExplodedTime *gmt)
{
#pragma unused (gmt)
PRTimeParameters retVal;
MachineLocation loc;
MyReadLocation(&loc);
/*
* On a Mac, the GMT value is in seconds east of GMT. For example,
* San Francisco is at -28,800 seconds (8 hours * 3600 seconds per hour)
* east of GMT. The gmtDelta field is a 3-byte value contained in a
* long word, so you must take care to get it properly.
*/
retVal.tp_gmt_offset = loc.u.gmtDelta & 0x00ffffff;
if (retVal.tp_gmt_offset & 0x00800000) { /* test sign extend bit */
retVal.tp_gmt_offset |= 0xff000000;
}
/*
* The daylight saving time value, dlsDelta, is a signed byte
* value representing the offset for the hour field -- whether
* to add 1 hour, subtract 1 hour, or make no change at all.
*/
if (loc.u.dlsDelta) {
retVal.tp_gmt_offset -= 3600;
retVal.tp_dst_offset = 3600;
} else {
retVal.tp_dst_offset = 0;
}
return retVal;
}
PRIntervalTime _MD_GetInterval(void)
{
PRIntervalTime retVal;
PRUint64 upTime, microtomilli;
/*
* Use the Microseconds procedure to obtain the number of
* microseconds elapsed since system startup time.
*/
Microseconds((UnsignedWide *)&upTime);
LL_I2L(microtomilli, PR_USEC_PER_MSEC);
LL_DIV(upTime, upTime, microtomilli);
LL_L2I(retVal, upTime);
return retVal;
}
struct tm *Maclocaltime(const time_t * t)
{
DateTimeRec dtr;
MachineLocation loc;
time_t macLocal = *t + gJanuaryFirst1970Seconds; /* GMT Mac */
static struct tm statictime;
static const short monthday[12] =
{0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334};
SecondsToDate(macLocal, &dtr);
statictime.tm_sec = dtr.second;
statictime.tm_min = dtr.minute;
statictime.tm_hour = dtr.hour;
statictime.tm_mday = dtr.day;
statictime.tm_mon = dtr.month - 1;
statictime.tm_year = dtr.year - 1900;
statictime.tm_wday = dtr.dayOfWeek - 1;
statictime.tm_yday = monthday[statictime.tm_mon]
+ statictime.tm_mday - 1;
if (2 < statictime.tm_mon && !(statictime.tm_year & 3))
++statictime.tm_yday;
MyReadLocation(&loc);
statictime.tm_isdst = loc.u.dlsDelta;
return(&statictime);
}
+51
View File
@@ -0,0 +1,51 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* 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 Portable Runtime (NSPR).
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998-2000
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef mactime_h__
#define mactime_h__
PR_BEGIN_EXTERN_C
void MacintoshInitializeTime(void);
PR_END_EXTERN_C
#endif /* mactime_h__ */
@@ -0,0 +1,173 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: NULL; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* 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 Portable Runtime (NSPR).
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998-2000
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* George Warner, Apple Computer Inc.
* Simon Fraser <sfraser@netscape.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "mdcriticalregion.h"
#include <MacErrors.h>
/*
This code is a replacement for MPEnterCriticalRegion/MPLeaveCriticalRegion,
which is broken on Mac OS 10.0.x builds, but fixed in 10.1. This code works
everywhere.
*/
typedef struct MDCriticalRegionData_struct {
MPTaskID mMPTaskID; /* Who's in the critical region? */
UInt32 mDepthCount; /* How deep? */
MPSemaphoreID mMPSemaphoreID; /* ready semaphore */
} MDCriticalRegionData, *MDCriticalRegionDataPtr;
OSStatus
MD_CriticalRegionCreate(MDCriticalRegionID * outCriticalRegionID)
{
MDCriticalRegionDataPtr newCriticalRegionPtr;
MPSemaphoreID mpSemaphoreID;
OSStatus err = noErr;
if (outCriticalRegionID == NULL)
return paramErr;
*outCriticalRegionID = NULL;
newCriticalRegionPtr = (MDCriticalRegionDataPtr)MPAllocateAligned(sizeof(MDCriticalRegionData),
kMPAllocateDefaultAligned, kMPAllocateClearMask);
if (newCriticalRegionPtr == NULL)
return memFullErr;
// Note: this semaphore is pre-fired (ready!)
err = MPCreateBinarySemaphore(&mpSemaphoreID);
if (err == noErr)
{
newCriticalRegionPtr->mMPTaskID = kInvalidID;
newCriticalRegionPtr->mDepthCount = 0;
newCriticalRegionPtr->mMPSemaphoreID = mpSemaphoreID;
*outCriticalRegionID = (MDCriticalRegionID)newCriticalRegionPtr;
}
else
{
MPFree((LogicalAddress)newCriticalRegionPtr);
}
return err;
}
OSStatus
MD_CriticalRegionDelete(MDCriticalRegionID inCriticalRegionID)
{
MDCriticalRegionDataPtr criticalRegion = (MDCriticalRegionDataPtr)inCriticalRegionID;
OSStatus err = noErr;
if (criticalRegion == NULL)
return paramErr;
if ((criticalRegion->mMPTaskID != kInvalidID) && (criticalRegion->mDepthCount > 0))
return kMPInsufficientResourcesErr;
if (criticalRegion->mMPSemaphoreID != kInvalidID)
err = MPDeleteSemaphore(criticalRegion->mMPSemaphoreID);
if (noErr != err) return err;
criticalRegion->mMPSemaphoreID = kInvalidID;
MPFree((LogicalAddress) criticalRegion);
return noErr;
}
OSStatus
MD_CriticalRegionEnter(MDCriticalRegionID inCriticalRegionID, Duration inTimeout)
{
MDCriticalRegionDataPtr criticalRegion = (MDCriticalRegionDataPtr)inCriticalRegionID;
MPTaskID currentTaskID = MPCurrentTaskID();
OSStatus err = noErr;
if (criticalRegion == NULL)
return paramErr;
// if I'm inside the critical region...
if (currentTaskID == criticalRegion->mMPTaskID)
{
// bump my depth
criticalRegion->mDepthCount++;
// and continue
return noErr;
}
// wait for the ready semaphore
err = MPWaitOnSemaphore(criticalRegion->mMPSemaphoreID, inTimeout);
// we didn't get it. return the error
if (noErr != err) return err;
// we got it!
criticalRegion->mMPTaskID = currentTaskID;
criticalRegion->mDepthCount = 1;
return noErr;
}
OSStatus
MD_CriticalRegionExit(MDCriticalRegionID inCriticalRegionID)
{
MDCriticalRegionDataPtr criticalRegion = (MDCriticalRegionDataPtr)inCriticalRegionID;
MPTaskID currentTaskID = MPCurrentTaskID();
OSStatus err = noErr;
// if we don't own the critical region...
if (currentTaskID != criticalRegion->mMPTaskID)
return kMPInsufficientResourcesErr;
// if we aren't at a depth...
if (criticalRegion->mDepthCount == 0)
return kMPInsufficientResourcesErr;
// un-bump my depth
criticalRegion->mDepthCount--;
// if we just bottomed out...
if (criticalRegion->mDepthCount == 0)
{
// release ownership of the structure
criticalRegion->mMPTaskID = kInvalidID;
// and signal the ready semaphore
err = MPSignalSemaphore(criticalRegion->mMPSemaphoreID);
}
return err;
}
@@ -0,0 +1,59 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* 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 Portable Runtime (NSPR).
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998-2000
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* George Warner, Apple Computer Inc.
* Simon Fraser <sfraser@netscape.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef mdcriticalregion_h___
#define mdcriticalregion_h___
#ifndef __MULTIPROCESSING__
#include <Multiprocessing.h>
#endif
typedef struct OpaqueMDCriticalRegionID* MDCriticalRegionID;
OSStatus MD_CriticalRegionCreate(MDCriticalRegionID * pMDCriticalRegionID);
OSStatus MD_CriticalRegionDelete(MDCriticalRegionID pMDCriticalRegionID);
OSStatus MD_CriticalRegionEnter(MDCriticalRegionID pMDCriticalRegionID, Duration pTimeout);
OSStatus MD_CriticalRegionExit(MDCriticalRegionID pMDCriticalRegionID);
#endif /* mdcriticalregion_h___ */
+776
View File
@@ -0,0 +1,776 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* 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 Portable Runtime (NSPR).
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998-2000
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include <Types.h>
#include <Timer.h>
#include <Files.h>
#include <Errors.h>
#include <Folders.h>
#include <Gestalt.h>
#include <Events.h>
#include <Processes.h>
#include <TextUtils.h>
#include <MixedMode.h>
#include <LowMem.h>
#include <fcntl.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <stat.h>
#include <stdarg.h>
#include <unix.h>
#include "MacErrorHandling.h"
#include "primpl.h"
#include "prgc.h"
#include "mactime.h"
#include "mdmac.h"
// undefine getenv, so that _MD_GetEnv can call the version in NSStdLib::nsEnvironment.cpp.
#undef getenv
//
// Local routines
//
unsigned char GarbageCollectorCacheFlusher(PRUint32 size);
extern PRThread *gPrimaryThread;
extern ProcessSerialNumber gApplicationProcess; // in macthr.c
//##############################################################################
//##############################################################################
#pragma mark -
#pragma mark CREATING MACINTOSH THREAD STACKS
enum {
uppExitToShellProcInfo = kPascalStackBased,
uppStackSpaceProcInfo = kRegisterBased
| RESULT_SIZE(SIZE_CODE(sizeof(long)))
| REGISTER_RESULT_LOCATION(kRegisterD0)
| REGISTER_ROUTINE_PARAMETER(1, kRegisterD1, SIZE_CODE(sizeof(UInt16)))
};
typedef CALLBACK_API( long , StackSpacePatchPtr )(UInt16 trapNo);
typedef REGISTER_UPP_TYPE(StackSpacePatchPtr) StackSpacePatchUPP;
StackSpacePatchUPP gStackSpacePatchUPP = NULL;
UniversalProcPtr gStackSpacePatchCallThru = NULL;
long (*gCallOSTrapUniversalProc)(UniversalProcPtr,ProcInfoType,...) = NULL;
pascal long StackSpacePatch(UInt16 trapNo)
{
char tos;
PRThread *thisThread;
thisThread = PR_GetCurrentThread();
// If we are the primary thread, then call through to the
// good ol' fashion stack space implementation. Otherwise,
// compute it by hand.
if ((thisThread == gPrimaryThread) ||
(&tos < thisThread->stack->stackBottom) ||
(&tos > thisThread->stack->stackTop)) {
return gCallOSTrapUniversalProc(gStackSpacePatchCallThru, uppStackSpaceProcInfo, trapNo);
}
else {
return &tos - thisThread->stack->stackBottom;
}
}
static void InstallStackSpacePatch(void)
{
long systemVersion;
OSErr err;
CFragConnectionID connID;
Str255 errMessage;
Ptr interfaceLibAddr;
CFragSymbolClass symClass;
UniversalProcPtr (*getOSTrapAddressProc)(UInt16);
void (*setOSTrapAddressProc)(StackSpacePatchUPP, UInt16);
UniversalProcPtr (*newRoutineDescriptorProc)(ProcPtr,ProcInfoType,ISAType);
err = Gestalt(gestaltSystemVersion,&systemVersion);
if (systemVersion >= 0x00000A00) // we don't need to patch StackSpace()
return;
// open connection to "InterfaceLib"
err = GetSharedLibrary("\pInterfaceLib", kPowerPCCFragArch, kFindCFrag,
&connID, &interfaceLibAddr, errMessage);
PR_ASSERT(err == noErr);
if (err != noErr)
return;
// get symbol GetOSTrapAddress
err = FindSymbol(connID, "\pGetOSTrapAddress", &(Ptr)getOSTrapAddressProc, &symClass);
if (err != noErr)
return;
// get symbol SetOSTrapAddress
err = FindSymbol(connID, "\pSetOSTrapAddress", &(Ptr)setOSTrapAddressProc, &symClass);
if (err != noErr)
return;
// get symbol NewRoutineDescriptor
err = FindSymbol(connID, "\pNewRoutineDescriptor", &(Ptr)newRoutineDescriptorProc, &symClass);
if (err != noErr)
return;
// get symbol CallOSTrapUniversalProc
err = FindSymbol(connID, "\pCallOSTrapUniversalProc", &(Ptr)gCallOSTrapUniversalProc, &symClass);
if (err != noErr)
return;
// get and set trap address for StackSpace (A065)
gStackSpacePatchCallThru = getOSTrapAddressProc(0x0065);
if (gStackSpacePatchCallThru)
{
gStackSpacePatchUPP =
(StackSpacePatchUPP)newRoutineDescriptorProc((ProcPtr)(StackSpacePatch), uppStackSpaceProcInfo, GetCurrentArchitecture());
setOSTrapAddressProc(gStackSpacePatchUPP, 0x0065);
}
#if DEBUG
StackSpace();
#endif
}
//##############################################################################
//##############################################################################
#pragma mark -
#pragma mark ENVIRONMENT VARIABLES
typedef struct EnvVariable EnvVariable;
struct EnvVariable {
char *variable;
char *value;
EnvVariable *next;
};
EnvVariable *gEnvironmentVariables = NULL;
char *_MD_GetEnv(const char *name)
{
EnvVariable *currentVariable = gEnvironmentVariables;
while (currentVariable) {
if (!strcmp(currentVariable->variable, name))
return currentVariable->value;
currentVariable = currentVariable->next;
}
return getenv(name);
}
PR_IMPLEMENT(int)
_MD_PutEnv(const char *string)
{
EnvVariable *currentVariable = gEnvironmentVariables;
char *variableCopy,
*value,
*current;
variableCopy = strdup(string);
PR_ASSERT(variableCopy != NULL);
current = variableCopy;
while (*current != '=')
current++;
*current = 0;
current++;
value = current;
while (currentVariable) {
if (!strcmp(currentVariable->variable, variableCopy))
break;
currentVariable = currentVariable->next;
}
if (currentVariable == NULL) {
currentVariable = PR_NEW(EnvVariable);
if (currentVariable == NULL) {
PR_DELETE(variableCopy);
return -1;
}
currentVariable->variable = strdup(variableCopy);
currentVariable->value = strdup(value);
currentVariable->next = gEnvironmentVariables;
gEnvironmentVariables = currentVariable;
}
else {
PR_DELETE(currentVariable->value);
currentVariable->value = strdup(current);
/* This is a temporary hack. Working on a real fix, remove this when done. */
/* OK, there are two ways to access the */
/* library path, getenv() and PR_GetLibraryPath(). Take a look at PR_GetLibraryPath(). */
/* You'll see that we keep the path in a global which is intialized at startup from */
/* a call to getenv(). From then on, they have nothing in common. */
/* We need to keep them in synch. */
if (strcmp(currentVariable->variable, "LD_LIBRARY_PATH") == 0)
PR_SetLibraryPath(currentVariable->value);
}
PR_DELETE(variableCopy);
return 0;
}
//##############################################################################
//##############################################################################
#pragma mark -
#pragma mark MISCELLANEOUS
PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np)
{
if (isCurrent) {
(void) setjmp(t->md.jb);
}
*np = sizeof(t->md.jb) / sizeof(PRUint32);
return (PRWord*) (t->md.jb);
}
void _MD_GetRegisters(PRUint32 *to)
{
(void) setjmp((void*) to);
}
void _MD_EarlyInit()
{
Handle environmentVariables;
GetCurrentProcess(&gApplicationProcess);
INIT_CRITICAL_REGION();
InitIdleSemaphore();
#if !defined(MAC_NSPR_STANDALONE)
// MacintoshInitializeMemory(); Moved to mdmacmem.c: AllocateRawMemory(Size blockSize)
#else
MacintoshInitializeMemory();
#endif
MacintoshInitializeTime();
// Install resource-controlled environment variables.
environmentVariables = GetResource('Envi', 128);
if (environmentVariables != NULL) {
Size resourceSize;
char *currentPutEnvString = (char *)*environmentVariables,
*currentScanChar = currentPutEnvString;
resourceSize = GetHandleSize(environmentVariables);
DetachResource(environmentVariables);
HLock(environmentVariables);
while (resourceSize--) {
if ((*currentScanChar == '\n') || (*currentScanChar == '\r')) {
*currentScanChar = 0;
_MD_PutEnv (currentPutEnvString);
currentPutEnvString = currentScanChar + 1;
}
currentScanChar++;
}
DisposeHandle(environmentVariables);
}
#ifdef PR_INTERNAL_LOGGING
_MD_PutEnv ("NSPR_LOG_MODULES=clock:6,cmon:6,io:6,mon:6,linker:6,cvar:6,sched:6,thread:6");
#endif
InstallStackSpacePatch();
}
void _MD_FinalInit()
{
_MD_InitNetAccess();
}
void PR_InitMemory(void) {
#ifndef NSPR_AS_SHARED_LIB
// Needed for Mac browsers without Java. We don't want them calling PR_INIT, since it
// brings in all of the thread support. But we do need to allow them to initialize
// the NSPR memory package.
// This should go away when all clients of the NSPR want threads AND memory.
MacintoshInitializeMemory();
#endif
}
//##############################################################################
//##############################################################################
#pragma mark -
#pragma mark TERMINATION
// THIS IS *** VERY *** IMPORTANT... our CFM Termination proc.
// This allows us to deactivate our Time Mananger task even
// if we are not totally gracefully exited. If this is not
// done then we will randomly crash at later times when the
// task is called after the app heap is gone.
#if TARGET_CARBON
extern OTClientContextPtr clientContext;
#define CLOSE_OPEN_TRANSPORT() CloseOpenTransportInContext(clientContext)
#else
#define CLOSE_OPEN_TRANSPORT() CloseOpenTransport()
#endif /* TARGET_CARBON */
extern pascal void __NSTerminate(void);
void CleanupTermProc(void)
{
_MD_StopInterrupts(); // deactive Time Manager task
CLOSE_OPEN_TRANSPORT();
TermIdleSemaphore();
TERM_CRITICAL_REGION();
__NSTerminate();
}
//##############################################################################
//##############################################################################
#pragma mark -
#pragma mark STRING OPERATIONS
#if !defined(MAC_NSPR_STANDALONE)
// PStrFromCStr converts the source C string to a destination
// pascal string as it copies. The dest string will
// be truncated to fit into an Str255 if necessary.
// If the C String pointer is NULL, the pascal string's length is set to zero
//
void
PStrFromCStr(const char* src, Str255 dst)
{
short length = 0;
// handle case of overlapping strings
if ( (void*)src == (void*)dst )
{
unsigned char* curdst = &dst[1];
unsigned char thisChar;
thisChar = *(const unsigned char*)src++;
while ( thisChar != '\0' )
{
unsigned char nextChar;
// use nextChar so we don't overwrite what we are about to read
nextChar = *(const unsigned char*)src++;
*curdst++ = thisChar;
thisChar = nextChar;
if ( ++length >= 255 )
break;
}
}
else if ( src != NULL )
{
unsigned char* curdst = &dst[1];
short overflow = 255; // count down so test it loop is faster
register char temp;
// Can't do the K&R C thing of "while (*s++ = *t++)" because it will copy trailing zero
// which might overrun pascal buffer. Instead we use a temp variable.
while ( (temp = *src++) != 0 )
{
*(char*)curdst++ = temp;
if ( --overflow <= 0 )
break;
}
length = 255 - overflow;
}
dst[0] = length;
}
void CStrFromPStr(ConstStr255Param pString, char **cString)
{
// Allocates a cString and copies a Pascal string into it.
unsigned int len;
len = pString[0];
*cString = malloc(len+1);
if (*cString != NULL) {
strncpy(*cString, (char *)&pString[1], len);
(*cString)[len] = NULL;
}
}
void dprintf(const char *format, ...)
{
#if DEBUG
va_list ap;
Str255 buffer;
va_start(ap, format);
buffer[0] = PR_vsnprintf((char *)buffer + 1, sizeof(buffer) - 1, format, ap);
va_end(ap);
DebugStr(buffer);
#endif /* DEBUG */
}
#else
void debugstr(const char *debuggerMsg)
{
Str255 pStr;
PStrFromCStr(debuggerMsg, pStr);
DebugStr(pStr);
}
char *strdup(const char *source)
{
char *newAllocation;
size_t stringLength;
PR_ASSERT(source);
stringLength = strlen(source) + 1;
newAllocation = (char *)PR_MALLOC(stringLength);
if (newAllocation == NULL)
return NULL;
BlockMoveData(source, newAllocation, stringLength);
return newAllocation;
}
// PStrFromCStr converts the source C string to a destination
// pascal string as it copies. The dest string will
// be truncated to fit into an Str255 if necessary.
// If the C String pointer is NULL, the pascal string's length is set to zero
//
void PStrFromCStr(const char* src, Str255 dst)
{
short length = 0;
// handle case of overlapping strings
if ( (void*)src == (void*)dst )
{
unsigned char* curdst = &dst[1];
unsigned char thisChar;
thisChar = *(const unsigned char*)src++;
while ( thisChar != '\0' )
{
unsigned char nextChar;
// use nextChar so we don't overwrite what we are about to read
nextChar = *(const unsigned char*)src++;
*curdst++ = thisChar;
thisChar = nextChar;
if ( ++length >= 255 )
break;
}
}
else if ( src != NULL )
{
unsigned char* curdst = &dst[1];
short overflow = 255; // count down so test it loop is faster
register char temp;
// Can't do the K&R C thing of "while (*s++ = *t++)" because it will copy trailing zero
// which might overrun pascal buffer. Instead we use a temp variable.
while ( (temp = *src++) != 0 )
{
*(char*)curdst++ = temp;
if ( --overflow <= 0 )
break;
}
length = 255 - overflow;
}
dst[0] = length;
}
void CStrFromPStr(ConstStr255Param pString, char **cString)
{
// Allocates a cString and copies a Pascal string into it.
unsigned int len;
len = pString[0];
*cString = PR_MALLOC(len+1);
if (*cString != NULL) {
strncpy(*cString, (char *)&pString[1], len);
(*cString)[len] = NULL;
}
}
size_t strlen(const char *source)
{
size_t currentLength = 0;
if (source == NULL)
return currentLength;
while (*source++ != '\0')
currentLength++;
return currentLength;
}
int strcmpcore(const char *str1, const char *str2, int caseSensitive)
{
char currentChar1, currentChar2;
while (1) {
currentChar1 = *str1;
currentChar2 = *str2;
if (!caseSensitive) {
if ((currentChar1 >= 'a') && (currentChar1 <= 'z'))
currentChar1 += ('A' - 'a');
if ((currentChar2 >= 'a') && (currentChar2 <= 'z'))
currentChar2 += ('A' - 'a');
}
if (currentChar1 == '\0')
break;
if (currentChar1 != currentChar2)
return currentChar1 - currentChar2;
str1++;
str2++;
}
return currentChar1 - currentChar2;
}
int strcmp(const char *str1, const char *str2)
{
return strcmpcore(str1, str2, true);
}
int strcasecmp(const char *str1, const char *str2)
{
return strcmpcore(str1, str2, false);
}
void *memcpy(void *to, const void *from, size_t size)
{
if (size != 0) {
#if DEBUG
if ((UInt32)to < 0x1000)
DebugStr("\pmemcpy has illegal to argument");
if ((UInt32)from < 0x1000)
DebugStr("\pmemcpy has illegal from argument");
#endif
BlockMoveData(from, to, size);
}
return to;
}
void dprintf(const char *format, ...)
{
va_list ap;
char *buffer;
va_start(ap, format);
buffer = (char *)PR_vsmprintf(format, ap);
va_end(ap);
debugstr(buffer);
PR_DELETE(buffer);
}
void
exit(int result)
{
#pragma unused (result)
ExitToShell();
}
void abort(void)
{
exit(-1);
}
#endif
//##############################################################################
//##############################################################################
#pragma mark -
#pragma mark FLUSHING THE GARBAGE COLLECTOR
#if !defined(MAC_NSPR_STANDALONE)
unsigned char GarbageCollectorCacheFlusher(PRUint32)
{
PRIntn is;
UInt32 oldPriority;
// If java wasn't completely initialized, then bail
// harmlessly.
if (PR_GetGCInfo()->lock == NULL)
return false;
#if DEBUG
if (_MD_GET_INTSOFF() == 1)
DebugStr("\pGarbageCollectorCacheFlusher at interrupt time!");
#endif
// The synchronization here is very tricky. We really
// don't want any other threads to run while we are
// cleaning up the gc heap... they could call malloc,
// and then we would be in trouble in a big way. So,
// we jack up our priority and that of the finalizer
// so that we won't yield to other threads.
// dkc 5/17/96
oldPriority = PR_GetThreadPriority(PR_GetCurrentThread());
_PR_INTSOFF(is);
_PR_SetThreadPriority(PR_GetCurrentThread(), (PRThreadPriority)30);
_PR_INTSON(is);
// Garbage collect twice. This will finalize any
// dangling AWT resources (images, components), and
// then free up their GC space, too.
// dkc 2/15/96
// interrupts must be on during PR_GC
PR_GC();
// By setting the finalizer priority to 31, then we
// ensure it will run before us. When it finishes
// its list of finalizations, it returns to us
// for the second garbage collection.
PR_Yield();
PR_GC();
// Restore our old priorities.
_PR_INTSOFF(is);
_PR_SetThreadPriority(PR_GetCurrentThread(), (PRThreadPriority)oldPriority);
_PR_INTSON(is);
return false;
}
#endif
//##############################################################################
//##############################################################################
#pragma mark -
#pragma mark MISCELLANEOUS-HACKS
//
// ***** HACK FIX THESE ****
//
extern long _MD_GetOSName(char *buf, long count)
{
long len;
len = PR_snprintf(buf, count, "Mac OS");
return 0;
}
extern long _MD_GetOSVersion(char *buf, long count)
{
long len;
len = PR_snprintf(buf, count, "7.5");
return 0;
}
extern long _MD_GetArchitecture(char *buf, long count)
{
long len;
#if defined(TARGET_CPU_PPC) && TARGET_CPU_PPC
len = PR_snprintf(buf, count, "PowerPC");
#else
len = PR_snprintf(buf, count, "Motorola68k");
#endif
return 0;
}
+51
View File
@@ -0,0 +1,51 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* 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 Portable Runtime (NSPR).
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998-2000
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef mdmac_h__
#define mdmac_h__
PR_BEGIN_EXTERN_C
void PStrFromCStr(const char* src, Str255 dst);
void CStrFromPStr(ConstStr255Param pString, char **cString);
PR_END_EXTERN_C
#endif /* mdmac_h__ */
+136
View File
@@ -0,0 +1,136 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* 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 Portable Runtime (NSPR).
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998-2000
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef nspr_cpucfg___
#define nspr_cpucfg___
#ifndef XP_MAC
#define XP_MAC
#endif
#undef IS_LITTLE_ENDIAN
#define IS_BIG_ENDIAN 1
#define HAVE_LONG_LONG
#define PR_AF_INET6 30 /* same as AF_INET6 */
#define PR_BYTES_PER_BYTE 1L
#define PR_BYTES_PER_SHORT 2L
#define PR_BYTES_PER_INT 4L
#define PR_BYTES_PER_INT64 8L
#define PR_BYTES_PER_LONG 4L
#define PR_BYTES_PER_FLOAT 4L
#define PR_BYTES_PER_DOUBLE 8L
#define PR_BYTES_PER_WORD 4L
#define PR_BYTES_PER_DWORD 8L
#define PR_BITS_PER_BYTE 8L
#define PR_BITS_PER_SHORT 16L
#define PR_BITS_PER_INT 32L
#define PR_BITS_PER_INT64 64L
#define PR_BITS_PER_LONG 32L
#define PR_BITS_PER_FLOAT 32L
#define PR_BITS_PER_DOUBLE 64L
#define PR_BITS_PER_WORD 32L
#define PR_BITS_PER_BYTE_LOG2 3L
#define PR_BITS_PER_SHORT_LOG2 4L
#define PR_BITS_PER_INT_LOG2 5L
#define PR_BITS_PER_INT64_LOG2 6L
#define PR_BITS_PER_LONG_LOG2 5L
#define PR_BITS_PER_FLOAT_LOG2 5L
#define PR_BITS_PER_DOUBLE_LOG2 6L
#define PR_BITS_PER_WORD_LOG2 5L
#define PR_ALIGN_OF_SHORT 2L
#define PR_ALIGN_OF_INT 4L
#define PR_ALIGN_OF_LONG 4L
#define PR_ALIGN_OF_INT64 2L
#define PR_ALIGN_OF_FLOAT 4L
#define PR_ALIGN_OF_DOUBLE 4L
#define PR_ALIGN_OF_POINTER 4L
#define PR_ALIGN_OF_WORD 4L
#define PR_BYTES_PER_WORD_LOG2 2L
#define PR_BYTES_PER_DWORD_LOG2 3L
#define PR_WORDS_PER_DWORD_LOG2 1L
#ifndef NO_NSPR_10_SUPPORT
#define BYTES_PER_BYTE PR_BYTES_PER_BYTE
#define BYTES_PER_SHORT PR_BYTES_PER_SHORT
#define BYTES_PER_INT PR_BYTES_PER_INT
#define BYTES_PER_INT64 PR_BYTES_PER_INT64
#define BYTES_PER_LONG PR_BYTES_PER_LONG
#define BYTES_PER_FLOAT PR_BYTES_PER_FLOAT
#define BYTES_PER_DOUBLE PR_BYTES_PER_DOUBLE
#define BYTES_PER_WORD PR_BYTES_PER_WORD
#define BYTES_PER_DWORD PR_BYTES_PER_DWORD
#define BITS_PER_BYTE PR_BITS_PER_BYTE
#define BITS_PER_SHORT PR_BITS_PER_SHORT
#define BITS_PER_INT PR_BITS_PER_INT
#define BITS_PER_INT64 PR_BITS_PER_INT64
#define BITS_PER_LONG PR_BITS_PER_LONG
#define BITS_PER_FLOAT PR_BITS_PER_FLOAT
#define BITS_PER_DOUBLE PR_BITS_PER_DOUBLE
#define BITS_PER_WORD PR_BITS_PER_WORD
#define BITS_PER_BYTE_LOG2 PR_BITS_PER_BYTE_LOG2
#define BITS_PER_SHORT_LOG2 PR_BITS_PER_SHORT_LOG2
#define BITS_PER_INT_LOG2 PR_BITS_PER_INT_LOG2
#define BITS_PER_INT64_LOG2 PR_BITS_PER_INT64_LOG2
#define BITS_PER_LONG_LOG2 PR_BITS_PER_LONG_LOG2
#define BITS_PER_FLOAT_LOG2 PR_BITS_PER_FLOAT_LOG2
#define BITS_PER_DOUBLE_LOG2 PR_BITS_PER_DOUBLE_LOG2
#define BITS_PER_WORD_LOG2 PR_BITS_PER_WORD_LOG2
#define ALIGN_OF_SHORT PR_ALIGN_OF_SHORT
#define ALIGN_OF_INT PR_ALIGN_OF_INT
#define ALIGN_OF_LONG PR_ALIGN_OF_LONG
#define ALIGN_OF_INT64 PR_ALIGN_OF_INT64
#define ALIGN_OF_FLOAT PR_ALIGN_OF_FLOAT
#define ALIGN_OF_DOUBLE PR_ALIGN_OF_DOUBLE
#define ALIGN_OF_POINTER PR_ALIGN_OF_POINTER
#define ALIGN_OF_WORD PR_ALIGN_OF_WORD
#define BYTES_PER_WORD_LOG2 PR_BYTES_PER_WORD_LOG2
#define BYTES_PER_DWORD_LOG2 PR_BYTES_PER_DWORD_LOG2
#define WORDS_PER_DWORD_LOG2 PR_WORDS_PER_DWORD_LOG2
#endif /* NO_NSPR_10_SUPPORT */
#endif /* nspr_cpucfg___ */