mirror of
https://github.com/python/cpython.git
synced 2025-07-28 13:44:43 +00:00
Untabify C files. Will watch buildbots.
This commit is contained in:
parent
368ede83d9
commit
c83ea137d7
318 changed files with 198669 additions and 198669 deletions
|
@ -4,61 +4,61 @@
|
|||
asdl_seq *
|
||||
asdl_seq_new(int size, PyArena *arena)
|
||||
{
|
||||
asdl_seq *seq = NULL;
|
||||
size_t n = (size ? (sizeof(void *) * (size - 1)) : 0);
|
||||
asdl_seq *seq = NULL;
|
||||
size_t n = (size ? (sizeof(void *) * (size - 1)) : 0);
|
||||
|
||||
/* check size is sane */
|
||||
if (size < 0 || size == INT_MIN ||
|
||||
(size && ((size - 1) > (PY_SIZE_MAX / sizeof(void *))))) {
|
||||
PyErr_NoMemory();
|
||||
return NULL;
|
||||
}
|
||||
/* check size is sane */
|
||||
if (size < 0 || size == INT_MIN ||
|
||||
(size && ((size - 1) > (PY_SIZE_MAX / sizeof(void *))))) {
|
||||
PyErr_NoMemory();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* check if size can be added safely */
|
||||
if (n > PY_SIZE_MAX - sizeof(asdl_seq)) {
|
||||
PyErr_NoMemory();
|
||||
return NULL;
|
||||
}
|
||||
/* check if size can be added safely */
|
||||
if (n > PY_SIZE_MAX - sizeof(asdl_seq)) {
|
||||
PyErr_NoMemory();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
n += sizeof(asdl_seq);
|
||||
n += sizeof(asdl_seq);
|
||||
|
||||
seq = (asdl_seq *)PyArena_Malloc(arena, n);
|
||||
if (!seq) {
|
||||
PyErr_NoMemory();
|
||||
return NULL;
|
||||
}
|
||||
memset(seq, 0, n);
|
||||
seq->size = size;
|
||||
return seq;
|
||||
seq = (asdl_seq *)PyArena_Malloc(arena, n);
|
||||
if (!seq) {
|
||||
PyErr_NoMemory();
|
||||
return NULL;
|
||||
}
|
||||
memset(seq, 0, n);
|
||||
seq->size = size;
|
||||
return seq;
|
||||
}
|
||||
|
||||
asdl_int_seq *
|
||||
asdl_int_seq_new(int size, PyArena *arena)
|
||||
{
|
||||
asdl_int_seq *seq = NULL;
|
||||
size_t n = (size ? (sizeof(void *) * (size - 1)) : 0);
|
||||
asdl_int_seq *seq = NULL;
|
||||
size_t n = (size ? (sizeof(void *) * (size - 1)) : 0);
|
||||
|
||||
/* check size is sane */
|
||||
if (size < 0 || size == INT_MIN ||
|
||||
(size && ((size - 1) > (PY_SIZE_MAX / sizeof(void *))))) {
|
||||
PyErr_NoMemory();
|
||||
return NULL;
|
||||
}
|
||||
/* check size is sane */
|
||||
if (size < 0 || size == INT_MIN ||
|
||||
(size && ((size - 1) > (PY_SIZE_MAX / sizeof(void *))))) {
|
||||
PyErr_NoMemory();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* check if size can be added safely */
|
||||
if (n > PY_SIZE_MAX - sizeof(asdl_seq)) {
|
||||
PyErr_NoMemory();
|
||||
return NULL;
|
||||
}
|
||||
/* check if size can be added safely */
|
||||
if (n > PY_SIZE_MAX - sizeof(asdl_seq)) {
|
||||
PyErr_NoMemory();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
n += sizeof(asdl_seq);
|
||||
n += sizeof(asdl_seq);
|
||||
|
||||
seq = (asdl_int_seq *)PyArena_Malloc(arena, n);
|
||||
if (!seq) {
|
||||
PyErr_NoMemory();
|
||||
return NULL;
|
||||
}
|
||||
memset(seq, 0, n);
|
||||
seq->size = size;
|
||||
return seq;
|
||||
seq = (asdl_int_seq *)PyArena_Malloc(arena, n);
|
||||
if (!seq) {
|
||||
PyErr_NoMemory();
|
||||
return NULL;
|
||||
}
|
||||
memset(seq, 0, n);
|
||||
seq->size = size;
|
||||
return seq;
|
||||
}
|
||||
|
|
|
@ -10,41 +10,41 @@
|
|||
|
||||
double atof(char *s)
|
||||
{
|
||||
double a = 0.0;
|
||||
int e = 0;
|
||||
int c;
|
||||
while ((c = *s++) != '\0' && isdigit(c)) {
|
||||
a = a*10.0 + (c - '0');
|
||||
}
|
||||
if (c == '.') {
|
||||
while ((c = *s++) != '\0' && isdigit(c)) {
|
||||
a = a*10.0 + (c - '0');
|
||||
e = e-1;
|
||||
}
|
||||
}
|
||||
if (c == 'e' || c == 'E') {
|
||||
int sign = 1;
|
||||
int i = 0;
|
||||
c = *s++;
|
||||
if (c == '+')
|
||||
c = *s++;
|
||||
else if (c == '-') {
|
||||
c = *s++;
|
||||
sign = -1;
|
||||
}
|
||||
while (isdigit(c)) {
|
||||
i = i*10 + (c - '0');
|
||||
c = *s++;
|
||||
}
|
||||
e += i*sign;
|
||||
}
|
||||
while (e > 0) {
|
||||
a *= 10.0;
|
||||
e--;
|
||||
}
|
||||
while (e < 0) {
|
||||
a *= 0.1;
|
||||
e++;
|
||||
}
|
||||
return a;
|
||||
double a = 0.0;
|
||||
int e = 0;
|
||||
int c;
|
||||
while ((c = *s++) != '\0' && isdigit(c)) {
|
||||
a = a*10.0 + (c - '0');
|
||||
}
|
||||
if (c == '.') {
|
||||
while ((c = *s++) != '\0' && isdigit(c)) {
|
||||
a = a*10.0 + (c - '0');
|
||||
e = e-1;
|
||||
}
|
||||
}
|
||||
if (c == 'e' || c == 'E') {
|
||||
int sign = 1;
|
||||
int i = 0;
|
||||
c = *s++;
|
||||
if (c == '+')
|
||||
c = *s++;
|
||||
else if (c == '-') {
|
||||
c = *s++;
|
||||
sign = -1;
|
||||
}
|
||||
while (isdigit(c)) {
|
||||
i = i*10 + (c - '0');
|
||||
c = *s++;
|
||||
}
|
||||
e += i*sign;
|
||||
}
|
||||
while (e > 0) {
|
||||
a *= 10.0;
|
||||
e--;
|
||||
}
|
||||
while (e < 0) {
|
||||
a *= 0.1;
|
||||
e++;
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
|
4014
Python/bltinmodule.c
4014
Python/bltinmodule.c
File diff suppressed because it is too large
Load diff
7490
Python/ceval.c
7490
Python/ceval.c
File diff suppressed because it is too large
Load diff
802
Python/codecs.c
802
Python/codecs.c
File diff suppressed because it is too large
Load diff
5878
Python/compile.c
5878
Python/compile.c
File diff suppressed because it is too large
Load diff
|
@ -4,10 +4,10 @@
|
|||
#include "Python.h"
|
||||
#include "importdl.h"
|
||||
|
||||
#include <ctype.h> /* for isdigit() */
|
||||
#include <errno.h> /* for global errno */
|
||||
#include <string.h> /* for strerror() */
|
||||
#include <stdlib.h> /* for malloc(), free() */
|
||||
#include <ctype.h> /* for isdigit() */
|
||||
#include <errno.h> /* for global errno */
|
||||
#include <string.h> /* for strerror() */
|
||||
#include <stdlib.h> /* for malloc(), free() */
|
||||
#include <sys/ldr.h>
|
||||
|
||||
|
||||
|
@ -22,85 +22,85 @@
|
|||
extern char *Py_GetProgramName(void);
|
||||
|
||||
typedef struct Module {
|
||||
struct Module *next;
|
||||
void *entry;
|
||||
struct Module *next;
|
||||
void *entry;
|
||||
} Module, *ModulePtr;
|
||||
|
||||
const struct filedescr _PyImport_DynLoadFiletab[] = {
|
||||
{".so", "rb", C_EXTENSION},
|
||||
{"module.so", "rb", C_EXTENSION},
|
||||
{0, 0}
|
||||
{".so", "rb", C_EXTENSION},
|
||||
{"module.so", "rb", C_EXTENSION},
|
||||
{0, 0}
|
||||
};
|
||||
|
||||
static int
|
||||
aix_getoldmodules(void **modlistptr)
|
||||
{
|
||||
register ModulePtr modptr, prevmodptr;
|
||||
register struct ld_info *ldiptr;
|
||||
register char *ldibuf;
|
||||
register int errflag, bufsize = 1024;
|
||||
register unsigned int offset;
|
||||
char *progname = Py_GetProgramName();
|
||||
|
||||
/*
|
||||
-- Get the list of loaded modules into ld_info structures.
|
||||
*/
|
||||
if ((ldibuf = malloc(bufsize)) == NULL) {
|
||||
PyErr_SetString(PyExc_ImportError, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
while ((errflag = loadquery(L_GETINFO, ldibuf, bufsize)) == -1
|
||||
&& errno == ENOMEM) {
|
||||
free(ldibuf);
|
||||
bufsize += 1024;
|
||||
if ((ldibuf = malloc(bufsize)) == NULL) {
|
||||
PyErr_SetString(PyExc_ImportError, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if (errflag == -1) {
|
||||
PyErr_SetString(PyExc_ImportError, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
/*
|
||||
-- Make the modules list from the ld_info structures.
|
||||
*/
|
||||
ldiptr = (struct ld_info *)ldibuf;
|
||||
prevmodptr = NULL;
|
||||
do {
|
||||
if (strstr(progname, ldiptr->ldinfo_filename) == NULL &&
|
||||
strstr(ldiptr->ldinfo_filename, "python") == NULL) {
|
||||
/*
|
||||
-- Extract only the modules belonging to the main
|
||||
-- executable + those containing "python" as a
|
||||
-- substring (like the "python[version]" binary or
|
||||
-- "libpython[version].a" in case it's a shared lib).
|
||||
*/
|
||||
offset = (unsigned int)ldiptr->ldinfo_next;
|
||||
ldiptr = (struct ld_info *)((char*)ldiptr + offset);
|
||||
continue;
|
||||
}
|
||||
if ((modptr = (ModulePtr)malloc(sizeof(Module))) == NULL) {
|
||||
PyErr_SetString(PyExc_ImportError, strerror(errno));
|
||||
while (*modlistptr) {
|
||||
modptr = (ModulePtr)*modlistptr;
|
||||
*modlistptr = (void *)modptr->next;
|
||||
free(modptr);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
modptr->entry = ldiptr->ldinfo_dataorg;
|
||||
modptr->next = NULL;
|
||||
if (prevmodptr == NULL)
|
||||
*modlistptr = (void *)modptr;
|
||||
else
|
||||
prevmodptr->next = modptr;
|
||||
prevmodptr = modptr;
|
||||
offset = (unsigned int)ldiptr->ldinfo_next;
|
||||
ldiptr = (struct ld_info *)((char*)ldiptr + offset);
|
||||
} while (offset);
|
||||
free(ldibuf);
|
||||
return 0;
|
||||
register ModulePtr modptr, prevmodptr;
|
||||
register struct ld_info *ldiptr;
|
||||
register char *ldibuf;
|
||||
register int errflag, bufsize = 1024;
|
||||
register unsigned int offset;
|
||||
char *progname = Py_GetProgramName();
|
||||
|
||||
/*
|
||||
-- Get the list of loaded modules into ld_info structures.
|
||||
*/
|
||||
if ((ldibuf = malloc(bufsize)) == NULL) {
|
||||
PyErr_SetString(PyExc_ImportError, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
while ((errflag = loadquery(L_GETINFO, ldibuf, bufsize)) == -1
|
||||
&& errno == ENOMEM) {
|
||||
free(ldibuf);
|
||||
bufsize += 1024;
|
||||
if ((ldibuf = malloc(bufsize)) == NULL) {
|
||||
PyErr_SetString(PyExc_ImportError, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if (errflag == -1) {
|
||||
PyErr_SetString(PyExc_ImportError, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
/*
|
||||
-- Make the modules list from the ld_info structures.
|
||||
*/
|
||||
ldiptr = (struct ld_info *)ldibuf;
|
||||
prevmodptr = NULL;
|
||||
do {
|
||||
if (strstr(progname, ldiptr->ldinfo_filename) == NULL &&
|
||||
strstr(ldiptr->ldinfo_filename, "python") == NULL) {
|
||||
/*
|
||||
-- Extract only the modules belonging to the main
|
||||
-- executable + those containing "python" as a
|
||||
-- substring (like the "python[version]" binary or
|
||||
-- "libpython[version].a" in case it's a shared lib).
|
||||
*/
|
||||
offset = (unsigned int)ldiptr->ldinfo_next;
|
||||
ldiptr = (struct ld_info *)((char*)ldiptr + offset);
|
||||
continue;
|
||||
}
|
||||
if ((modptr = (ModulePtr)malloc(sizeof(Module))) == NULL) {
|
||||
PyErr_SetString(PyExc_ImportError, strerror(errno));
|
||||
while (*modlistptr) {
|
||||
modptr = (ModulePtr)*modlistptr;
|
||||
*modlistptr = (void *)modptr->next;
|
||||
free(modptr);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
modptr->entry = ldiptr->ldinfo_dataorg;
|
||||
modptr->next = NULL;
|
||||
if (prevmodptr == NULL)
|
||||
*modlistptr = (void *)modptr;
|
||||
else
|
||||
prevmodptr->next = modptr;
|
||||
prevmodptr = modptr;
|
||||
offset = (unsigned int)ldiptr->ldinfo_next;
|
||||
ldiptr = (struct ld_info *)((char*)ldiptr + offset);
|
||||
} while (offset);
|
||||
free(ldibuf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -108,76 +108,76 @@ static void
|
|||
aix_loaderror(const char *pathname)
|
||||
{
|
||||
|
||||
char *message[1024], errbuf[1024];
|
||||
register int i,j;
|
||||
char *message[1024], errbuf[1024];
|
||||
register int i,j;
|
||||
|
||||
struct errtab {
|
||||
int errNo;
|
||||
char *errstr;
|
||||
} load_errtab[] = {
|
||||
{L_ERROR_TOOMANY, "too many errors, rest skipped."},
|
||||
{L_ERROR_NOLIB, "can't load library:"},
|
||||
{L_ERROR_UNDEF, "can't find symbol in library:"},
|
||||
{L_ERROR_RLDBAD,
|
||||
"RLD index out of range or bad relocation type:"},
|
||||
{L_ERROR_FORMAT, "not a valid, executable xcoff file:"},
|
||||
{L_ERROR_MEMBER,
|
||||
"file not an archive or does not contain requested member:"},
|
||||
{L_ERROR_TYPE, "symbol table mismatch:"},
|
||||
{L_ERROR_ALIGN, "text alignment in file is wrong."},
|
||||
{L_ERROR_SYSTEM, "System error:"},
|
||||
{L_ERROR_ERRNO, NULL}
|
||||
};
|
||||
struct errtab {
|
||||
int errNo;
|
||||
char *errstr;
|
||||
} load_errtab[] = {
|
||||
{L_ERROR_TOOMANY, "too many errors, rest skipped."},
|
||||
{L_ERROR_NOLIB, "can't load library:"},
|
||||
{L_ERROR_UNDEF, "can't find symbol in library:"},
|
||||
{L_ERROR_RLDBAD,
|
||||
"RLD index out of range or bad relocation type:"},
|
||||
{L_ERROR_FORMAT, "not a valid, executable xcoff file:"},
|
||||
{L_ERROR_MEMBER,
|
||||
"file not an archive or does not contain requested member:"},
|
||||
{L_ERROR_TYPE, "symbol table mismatch:"},
|
||||
{L_ERROR_ALIGN, "text alignment in file is wrong."},
|
||||
{L_ERROR_SYSTEM, "System error:"},
|
||||
{L_ERROR_ERRNO, NULL}
|
||||
};
|
||||
|
||||
#define LOAD_ERRTAB_LEN (sizeof(load_errtab)/sizeof(load_errtab[0]))
|
||||
#define LOAD_ERRTAB_LEN (sizeof(load_errtab)/sizeof(load_errtab[0]))
|
||||
#define ERRBUF_APPEND(s) strncat(errbuf, s, sizeof(errbuf)-strlen(errbuf)-1)
|
||||
|
||||
PyOS_snprintf(errbuf, sizeof(errbuf), "from module %.200s ", pathname);
|
||||
PyOS_snprintf(errbuf, sizeof(errbuf), "from module %.200s ", pathname);
|
||||
|
||||
if (!loadquery(L_GETMESSAGES, &message[0], sizeof(message))) {
|
||||
ERRBUF_APPEND(strerror(errno));
|
||||
ERRBUF_APPEND("\n");
|
||||
}
|
||||
for(i = 0; message[i] && *message[i]; i++) {
|
||||
int nerr = atoi(message[i]);
|
||||
for (j=0; j<LOAD_ERRTAB_LEN ; j++) {
|
||||
if (nerr == load_errtab[j].errNo && load_errtab[j].errstr)
|
||||
ERRBUF_APPEND(load_errtab[j].errstr);
|
||||
}
|
||||
while (isdigit(Py_CHARMASK(*message[i]))) message[i]++ ;
|
||||
ERRBUF_APPEND(message[i]);
|
||||
ERRBUF_APPEND("\n");
|
||||
}
|
||||
errbuf[strlen(errbuf)-1] = '\0'; /* trim off last newline */
|
||||
PyErr_SetString(PyExc_ImportError, errbuf);
|
||||
return;
|
||||
if (!loadquery(L_GETMESSAGES, &message[0], sizeof(message))) {
|
||||
ERRBUF_APPEND(strerror(errno));
|
||||
ERRBUF_APPEND("\n");
|
||||
}
|
||||
for(i = 0; message[i] && *message[i]; i++) {
|
||||
int nerr = atoi(message[i]);
|
||||
for (j=0; j<LOAD_ERRTAB_LEN ; j++) {
|
||||
if (nerr == load_errtab[j].errNo && load_errtab[j].errstr)
|
||||
ERRBUF_APPEND(load_errtab[j].errstr);
|
||||
}
|
||||
while (isdigit(Py_CHARMASK(*message[i]))) message[i]++ ;
|
||||
ERRBUF_APPEND(message[i]);
|
||||
ERRBUF_APPEND("\n");
|
||||
}
|
||||
errbuf[strlen(errbuf)-1] = '\0'; /* trim off last newline */
|
||||
PyErr_SetString(PyExc_ImportError, errbuf);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
dl_funcptr _PyImport_GetDynLoadFunc(const char *fqname, const char *shortname,
|
||||
const char *pathname, FILE *fp)
|
||||
const char *pathname, FILE *fp)
|
||||
{
|
||||
dl_funcptr p;
|
||||
dl_funcptr p;
|
||||
|
||||
/*
|
||||
-- Invoke load() with L_NOAUTODEFER leaving the imported symbols
|
||||
-- of the shared module unresolved. Thus we have to resolve them
|
||||
-- explicitly with loadbind. The new module is loaded, then we
|
||||
-- resolve its symbols using the list of already loaded modules
|
||||
-- (only those that belong to the python executable). Get these
|
||||
-- with loadquery(L_GETINFO).
|
||||
*/
|
||||
/*
|
||||
-- Invoke load() with L_NOAUTODEFER leaving the imported symbols
|
||||
-- of the shared module unresolved. Thus we have to resolve them
|
||||
-- explicitly with loadbind. The new module is loaded, then we
|
||||
-- resolve its symbols using the list of already loaded modules
|
||||
-- (only those that belong to the python executable). Get these
|
||||
-- with loadquery(L_GETINFO).
|
||||
*/
|
||||
|
||||
static void *staticmodlistptr = NULL;
|
||||
static void *staticmodlistptr = NULL;
|
||||
|
||||
if (!staticmodlistptr)
|
||||
if (aix_getoldmodules(&staticmodlistptr) == -1)
|
||||
return NULL;
|
||||
p = (dl_funcptr) aix_load((char *)pathname, L_NOAUTODEFER, 0);
|
||||
if (p == NULL) {
|
||||
aix_loaderror(pathname);
|
||||
return NULL;
|
||||
}
|
||||
if (!staticmodlistptr)
|
||||
if (aix_getoldmodules(&staticmodlistptr) == -1)
|
||||
return NULL;
|
||||
p = (dl_funcptr) aix_load((char *)pathname, L_NOAUTODEFER, 0);
|
||||
if (p == NULL) {
|
||||
aix_loaderror(pathname);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return p;
|
||||
return p;
|
||||
}
|
||||
|
|
|
@ -9,39 +9,39 @@
|
|||
|
||||
|
||||
const struct filedescr _PyImport_DynLoadFiletab[] = {
|
||||
{".so", "rb", C_EXTENSION},
|
||||
{"module.so", "rb", C_EXTENSION},
|
||||
{0, 0}
|
||||
{".so", "rb", C_EXTENSION},
|
||||
{"module.so", "rb", C_EXTENSION},
|
||||
{0, 0}
|
||||
};
|
||||
|
||||
dl_funcptr _PyImport_GetDynLoadFunc(const char *fqname, const char *shortname,
|
||||
const char *pathname, FILE *fp)
|
||||
const char *pathname, FILE *fp)
|
||||
{
|
||||
void *p;
|
||||
int lib;
|
||||
char funcname[258];
|
||||
void *p;
|
||||
int lib;
|
||||
char funcname[258];
|
||||
|
||||
if (Py_VerboseFlag)
|
||||
printf("load_library %s\n", pathname);
|
||||
if (Py_VerboseFlag)
|
||||
printf("load_library %s\n", pathname);
|
||||
|
||||
lib = load_library(pathname, 0);
|
||||
if (lib < 0) {
|
||||
char buf[512];
|
||||
if (Py_VerboseFlag)
|
||||
perror(pathname);
|
||||
PyOS_snprintf(buf, sizeof(buf), "Failed to load %.200s: %.200s",
|
||||
pathname, strerror(errno));
|
||||
PyErr_SetString(PyExc_ImportError, buf);
|
||||
return NULL;
|
||||
}
|
||||
PyOS_snprintf(funcname, sizeof(funcname), "init%.200s", shortname);
|
||||
if (Py_VerboseFlag)
|
||||
printf("get_symbol_address %s\n", funcname);
|
||||
if (get_symbol_address(lib, funcname, -1, &p) < 0) {
|
||||
p = NULL;
|
||||
if (Py_VerboseFlag)
|
||||
perror(funcname);
|
||||
}
|
||||
lib = load_library(pathname, 0);
|
||||
if (lib < 0) {
|
||||
char buf[512];
|
||||
if (Py_VerboseFlag)
|
||||
perror(pathname);
|
||||
PyOS_snprintf(buf, sizeof(buf), "Failed to load %.200s: %.200s",
|
||||
pathname, strerror(errno));
|
||||
PyErr_SetString(PyExc_ImportError, buf);
|
||||
return NULL;
|
||||
}
|
||||
PyOS_snprintf(funcname, sizeof(funcname), "init%.200s", shortname);
|
||||
if (Py_VerboseFlag)
|
||||
printf("get_symbol_address %s\n", funcname);
|
||||
if (get_symbol_address(lib, funcname, -1, &p) < 0) {
|
||||
p = NULL;
|
||||
if (Py_VerboseFlag)
|
||||
perror(funcname);
|
||||
}
|
||||
|
||||
return (dl_funcptr) p;
|
||||
return (dl_funcptr) p;
|
||||
}
|
||||
|
|
|
@ -9,9 +9,9 @@
|
|||
#include "importdl.h"
|
||||
|
||||
const struct filedescr _PyImport_DynLoadFiletab[] = {
|
||||
{".so", "rb", C_EXTENSION},
|
||||
{"module.so", "rb", C_EXTENSION},
|
||||
{0, 0}
|
||||
{".so", "rb", C_EXTENSION},
|
||||
{"module.so", "rb", C_EXTENSION},
|
||||
{0, 0}
|
||||
};
|
||||
|
||||
#if defined(MAXPATHLEN) && !defined(_SYS_PARAM_H)
|
||||
|
@ -52,13 +52,13 @@ static PyObject *beos_dyn_images = NULL;
|
|||
*/
|
||||
static void beos_nuke_dyn( PyObject *item )
|
||||
{
|
||||
status_t retval;
|
||||
status_t retval;
|
||||
|
||||
if( item ) {
|
||||
image_id id = (image_id)PyInt_AsLong( item );
|
||||
|
||||
retval = unload_add_on( id );
|
||||
}
|
||||
if( item ) {
|
||||
image_id id = (image_id)PyInt_AsLong( item );
|
||||
|
||||
retval = unload_add_on( id );
|
||||
}
|
||||
}
|
||||
|
||||
/* atexit() handler that'll call unload_add_on() for every item in the
|
||||
|
@ -66,31 +66,31 @@ static void beos_nuke_dyn( PyObject *item )
|
|||
*/
|
||||
static void beos_cleanup_dyn( void )
|
||||
{
|
||||
if( beos_dyn_images ) {
|
||||
int idx;
|
||||
int list_size;
|
||||
PyObject *id_list;
|
||||
if( beos_dyn_images ) {
|
||||
int idx;
|
||||
int list_size;
|
||||
PyObject *id_list;
|
||||
|
||||
#ifdef WITH_THREAD
|
||||
PyThread_acquire_lock( beos_dyn_lock, 1 );
|
||||
PyThread_acquire_lock( beos_dyn_lock, 1 );
|
||||
#endif
|
||||
|
||||
id_list = PyDict_Values( beos_dyn_images );
|
||||
id_list = PyDict_Values( beos_dyn_images );
|
||||
|
||||
list_size = PyList_Size( id_list );
|
||||
for( idx = 0; idx < list_size; idx++ ) {
|
||||
PyObject *the_item;
|
||||
|
||||
the_item = PyList_GetItem( id_list, idx );
|
||||
beos_nuke_dyn( the_item );
|
||||
}
|
||||
list_size = PyList_Size( id_list );
|
||||
for( idx = 0; idx < list_size; idx++ ) {
|
||||
PyObject *the_item;
|
||||
|
||||
PyDict_Clear( beos_dyn_images );
|
||||
the_item = PyList_GetItem( id_list, idx );
|
||||
beos_nuke_dyn( the_item );
|
||||
}
|
||||
|
||||
PyDict_Clear( beos_dyn_images );
|
||||
|
||||
#ifdef WITH_THREAD
|
||||
PyThread_free_lock( beos_dyn_lock );
|
||||
PyThread_free_lock( beos_dyn_lock );
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -98,20 +98,20 @@ static void beos_cleanup_dyn( void )
|
|||
*/
|
||||
static void beos_init_dyn( void )
|
||||
{
|
||||
/* We're protected from a race condition here by the atomic init_count
|
||||
* variable.
|
||||
*/
|
||||
static int32 init_count = 0;
|
||||
int32 val;
|
||||
/* We're protected from a race condition here by the atomic init_count
|
||||
* variable.
|
||||
*/
|
||||
static int32 init_count = 0;
|
||||
int32 val;
|
||||
|
||||
val = atomic_add( &init_count, 1 );
|
||||
if( beos_dyn_images == NULL && val == 0 ) {
|
||||
beos_dyn_images = PyDict_New();
|
||||
val = atomic_add( &init_count, 1 );
|
||||
if( beos_dyn_images == NULL && val == 0 ) {
|
||||
beos_dyn_images = PyDict_New();
|
||||
#ifdef WITH_THREAD
|
||||
beos_dyn_lock = PyThread_allocate_lock();
|
||||
beos_dyn_lock = PyThread_allocate_lock();
|
||||
#endif
|
||||
atexit( beos_cleanup_dyn );
|
||||
}
|
||||
atexit( beos_cleanup_dyn );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -122,133 +122,133 @@ static void beos_init_dyn( void )
|
|||
*/
|
||||
static void beos_add_dyn( char *name, image_id id )
|
||||
{
|
||||
int retval;
|
||||
PyObject *py_id;
|
||||
int retval;
|
||||
PyObject *py_id;
|
||||
|
||||
if( beos_dyn_images == NULL ) {
|
||||
beos_init_dyn();
|
||||
}
|
||||
if( beos_dyn_images == NULL ) {
|
||||
beos_init_dyn();
|
||||
}
|
||||
|
||||
#ifdef WITH_THREAD
|
||||
retval = PyThread_acquire_lock( beos_dyn_lock, 1 );
|
||||
retval = PyThread_acquire_lock( beos_dyn_lock, 1 );
|
||||
#endif
|
||||
|
||||
/* If there's already an object with this key in the dictionary,
|
||||
* we're doing a reload(), so let's nuke it.
|
||||
*/
|
||||
py_id = PyDict_GetItemString( beos_dyn_images, name );
|
||||
if( py_id ) {
|
||||
beos_nuke_dyn( py_id );
|
||||
retval = PyDict_DelItemString( beos_dyn_images, name );
|
||||
}
|
||||
/* If there's already an object with this key in the dictionary,
|
||||
* we're doing a reload(), so let's nuke it.
|
||||
*/
|
||||
py_id = PyDict_GetItemString( beos_dyn_images, name );
|
||||
if( py_id ) {
|
||||
beos_nuke_dyn( py_id );
|
||||
retval = PyDict_DelItemString( beos_dyn_images, name );
|
||||
}
|
||||
|
||||
py_id = PyInt_FromLong( (long)id );
|
||||
if( py_id ) {
|
||||
retval = PyDict_SetItemString( beos_dyn_images, name, py_id );
|
||||
}
|
||||
py_id = PyInt_FromLong( (long)id );
|
||||
if( py_id ) {
|
||||
retval = PyDict_SetItemString( beos_dyn_images, name, py_id );
|
||||
}
|
||||
|
||||
#ifdef WITH_THREAD
|
||||
PyThread_release_lock( beos_dyn_lock );
|
||||
PyThread_release_lock( beos_dyn_lock );
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
dl_funcptr _PyImport_GetDynLoadFunc(const char *fqname, const char *shortname,
|
||||
const char *pathname, FILE *fp)
|
||||
const char *pathname, FILE *fp)
|
||||
{
|
||||
dl_funcptr p;
|
||||
image_id the_id;
|
||||
status_t retval;
|
||||
char fullpath[PATH_MAX];
|
||||
char funcname[258];
|
||||
dl_funcptr p;
|
||||
image_id the_id;
|
||||
status_t retval;
|
||||
char fullpath[PATH_MAX];
|
||||
char funcname[258];
|
||||
|
||||
if( Py_VerboseFlag ) {
|
||||
printf( "load_add_on( %s )\n", pathname );
|
||||
}
|
||||
if( Py_VerboseFlag ) {
|
||||
printf( "load_add_on( %s )\n", pathname );
|
||||
}
|
||||
|
||||
/* Hmm, this old bug appears to have regenerated itself; if the
|
||||
* path isn't absolute, load_add_on() will fail. Reported to Be
|
||||
* April 21, 1998.
|
||||
*/
|
||||
if( pathname[0] != '/' ) {
|
||||
(void)getcwd( fullpath, PATH_MAX );
|
||||
(void)strncat( fullpath, "/", PATH_MAX );
|
||||
(void)strncat( fullpath, pathname, PATH_MAX );
|
||||
|
||||
if( Py_VerboseFlag ) {
|
||||
printf( "load_add_on( %s )\n", fullpath );
|
||||
}
|
||||
} else {
|
||||
(void)strcpy( fullpath, pathname );
|
||||
}
|
||||
/* Hmm, this old bug appears to have regenerated itself; if the
|
||||
* path isn't absolute, load_add_on() will fail. Reported to Be
|
||||
* April 21, 1998.
|
||||
*/
|
||||
if( pathname[0] != '/' ) {
|
||||
(void)getcwd( fullpath, PATH_MAX );
|
||||
(void)strncat( fullpath, "/", PATH_MAX );
|
||||
(void)strncat( fullpath, pathname, PATH_MAX );
|
||||
|
||||
the_id = load_add_on( fullpath );
|
||||
if( the_id < B_NO_ERROR ) {
|
||||
/* It's too bad load_add_on() doesn't set errno or something...
|
||||
*/
|
||||
char buff[256]; /* hate hard-coded string sizes... */
|
||||
if( Py_VerboseFlag ) {
|
||||
printf( "load_add_on( %s )\n", fullpath );
|
||||
}
|
||||
} else {
|
||||
(void)strcpy( fullpath, pathname );
|
||||
}
|
||||
|
||||
if( Py_VerboseFlag ) {
|
||||
printf( "load_add_on( %s ) failed", fullpath );
|
||||
}
|
||||
the_id = load_add_on( fullpath );
|
||||
if( the_id < B_NO_ERROR ) {
|
||||
/* It's too bad load_add_on() doesn't set errno or something...
|
||||
*/
|
||||
char buff[256]; /* hate hard-coded string sizes... */
|
||||
|
||||
if( the_id == B_ERROR )
|
||||
PyOS_snprintf( buff, sizeof(buff),
|
||||
"BeOS: Failed to load %.200s",
|
||||
fullpath );
|
||||
else
|
||||
PyOS_snprintf( buff, sizeof(buff),
|
||||
"Unknown error loading %.200s",
|
||||
fullpath );
|
||||
if( Py_VerboseFlag ) {
|
||||
printf( "load_add_on( %s ) failed", fullpath );
|
||||
}
|
||||
|
||||
PyErr_SetString( PyExc_ImportError, buff );
|
||||
return NULL;
|
||||
}
|
||||
if( the_id == B_ERROR )
|
||||
PyOS_snprintf( buff, sizeof(buff),
|
||||
"BeOS: Failed to load %.200s",
|
||||
fullpath );
|
||||
else
|
||||
PyOS_snprintf( buff, sizeof(buff),
|
||||
"Unknown error loading %.200s",
|
||||
fullpath );
|
||||
|
||||
PyOS_snprintf(funcname, sizeof(funcname), "init%.200s", shortname);
|
||||
if( Py_VerboseFlag ) {
|
||||
printf( "get_image_symbol( %s )\n", funcname );
|
||||
}
|
||||
PyErr_SetString( PyExc_ImportError, buff );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
retval = get_image_symbol( the_id, funcname, B_SYMBOL_TYPE_TEXT, &p );
|
||||
if( retval != B_NO_ERROR || p == NULL ) {
|
||||
/* That's bad, we can't find that symbol in the module...
|
||||
*/
|
||||
char buff[256]; /* hate hard-coded string sizes... */
|
||||
PyOS_snprintf(funcname, sizeof(funcname), "init%.200s", shortname);
|
||||
if( Py_VerboseFlag ) {
|
||||
printf( "get_image_symbol( %s )\n", funcname );
|
||||
}
|
||||
|
||||
if( Py_VerboseFlag ) {
|
||||
printf( "get_image_symbol( %s ) failed", funcname );
|
||||
}
|
||||
retval = get_image_symbol( the_id, funcname, B_SYMBOL_TYPE_TEXT, &p );
|
||||
if( retval != B_NO_ERROR || p == NULL ) {
|
||||
/* That's bad, we can't find that symbol in the module...
|
||||
*/
|
||||
char buff[256]; /* hate hard-coded string sizes... */
|
||||
|
||||
switch( retval ) {
|
||||
case B_BAD_IMAGE_ID:
|
||||
PyOS_snprintf( buff, sizeof(buff),
|
||||
"can't load init function for dynamic module: "
|
||||
"Invalid image ID for %.180s", fullpath );
|
||||
break;
|
||||
case B_BAD_INDEX:
|
||||
PyOS_snprintf( buff, sizeof(buff),
|
||||
"can't load init function for dynamic module: "
|
||||
"Bad index for %.180s", funcname );
|
||||
break;
|
||||
default:
|
||||
PyOS_snprintf( buff, sizeof(buff),
|
||||
"can't load init function for dynamic module: "
|
||||
"Unknown error looking up %.180s", funcname );
|
||||
break;
|
||||
}
|
||||
if( Py_VerboseFlag ) {
|
||||
printf( "get_image_symbol( %s ) failed", funcname );
|
||||
}
|
||||
|
||||
retval = unload_add_on( the_id );
|
||||
switch( retval ) {
|
||||
case B_BAD_IMAGE_ID:
|
||||
PyOS_snprintf( buff, sizeof(buff),
|
||||
"can't load init function for dynamic module: "
|
||||
"Invalid image ID for %.180s", fullpath );
|
||||
break;
|
||||
case B_BAD_INDEX:
|
||||
PyOS_snprintf( buff, sizeof(buff),
|
||||
"can't load init function for dynamic module: "
|
||||
"Bad index for %.180s", funcname );
|
||||
break;
|
||||
default:
|
||||
PyOS_snprintf( buff, sizeof(buff),
|
||||
"can't load init function for dynamic module: "
|
||||
"Unknown error looking up %.180s", funcname );
|
||||
break;
|
||||
}
|
||||
|
||||
PyErr_SetString( PyExc_ImportError, buff );
|
||||
return NULL;
|
||||
}
|
||||
retval = unload_add_on( the_id );
|
||||
|
||||
/* Save the module name and image ID for later so we can clean up
|
||||
* gracefully.
|
||||
*/
|
||||
beos_add_dyn( fqname, the_id );
|
||||
PyErr_SetString( PyExc_ImportError, buff );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return p;
|
||||
/* Save the module name and image ID for later so we can clean up
|
||||
* gracefully.
|
||||
*/
|
||||
beos_add_dyn( fqname, the_id );
|
||||
|
||||
return p;
|
||||
}
|
||||
|
|
|
@ -14,45 +14,45 @@
|
|||
#endif
|
||||
|
||||
const struct filedescr _PyImport_DynLoadFiletab[] = {
|
||||
{SHLIB_EXT, "rb", C_EXTENSION},
|
||||
{"module"SHLIB_EXT, "rb", C_EXTENSION},
|
||||
{0, 0}
|
||||
{SHLIB_EXT, "rb", C_EXTENSION},
|
||||
{"module"SHLIB_EXT, "rb", C_EXTENSION},
|
||||
{0, 0}
|
||||
};
|
||||
|
||||
dl_funcptr _PyImport_GetDynLoadFunc(const char *fqname, const char *shortname,
|
||||
const char *pathname, FILE *fp)
|
||||
const char *pathname, FILE *fp)
|
||||
{
|
||||
dl_funcptr p;
|
||||
shl_t lib;
|
||||
int flags;
|
||||
char funcname[258];
|
||||
dl_funcptr p;
|
||||
shl_t lib;
|
||||
int flags;
|
||||
char funcname[258];
|
||||
|
||||
flags = BIND_FIRST | BIND_DEFERRED;
|
||||
if (Py_VerboseFlag) {
|
||||
flags = BIND_FIRST | BIND_IMMEDIATE |
|
||||
BIND_NONFATAL | BIND_VERBOSE;
|
||||
printf("shl_load %s\n",pathname);
|
||||
}
|
||||
lib = shl_load(pathname, flags, 0);
|
||||
/* XXX Chuck Blake once wrote that 0 should be BIND_NOSTART? */
|
||||
if (lib == NULL) {
|
||||
char buf[256];
|
||||
if (Py_VerboseFlag)
|
||||
perror(pathname);
|
||||
PyOS_snprintf(buf, sizeof(buf), "Failed to load %.200s",
|
||||
pathname);
|
||||
PyErr_SetString(PyExc_ImportError, buf);
|
||||
return NULL;
|
||||
}
|
||||
PyOS_snprintf(funcname, sizeof(funcname), FUNCNAME_PATTERN, shortname);
|
||||
if (Py_VerboseFlag)
|
||||
printf("shl_findsym %s\n", funcname);
|
||||
if (shl_findsym(&lib, funcname, TYPE_UNDEFINED, (void *) &p) == -1) {
|
||||
shl_unload(lib);
|
||||
p = NULL;
|
||||
}
|
||||
if (p == NULL && Py_VerboseFlag)
|
||||
perror(funcname);
|
||||
flags = BIND_FIRST | BIND_DEFERRED;
|
||||
if (Py_VerboseFlag) {
|
||||
flags = BIND_FIRST | BIND_IMMEDIATE |
|
||||
BIND_NONFATAL | BIND_VERBOSE;
|
||||
printf("shl_load %s\n",pathname);
|
||||
}
|
||||
lib = shl_load(pathname, flags, 0);
|
||||
/* XXX Chuck Blake once wrote that 0 should be BIND_NOSTART? */
|
||||
if (lib == NULL) {
|
||||
char buf[256];
|
||||
if (Py_VerboseFlag)
|
||||
perror(pathname);
|
||||
PyOS_snprintf(buf, sizeof(buf), "Failed to load %.200s",
|
||||
pathname);
|
||||
PyErr_SetString(PyExc_ImportError, buf);
|
||||
return NULL;
|
||||
}
|
||||
PyOS_snprintf(funcname, sizeof(funcname), FUNCNAME_PATTERN, shortname);
|
||||
if (Py_VerboseFlag)
|
||||
printf("shl_findsym %s\n", funcname);
|
||||
if (shl_findsym(&lib, funcname, TYPE_UNDEFINED, (void *) &p) == -1) {
|
||||
shl_unload(lib);
|
||||
p = NULL;
|
||||
}
|
||||
if (p == NULL && Py_VerboseFlag)
|
||||
perror(funcname);
|
||||
|
||||
return p;
|
||||
return p;
|
||||
}
|
||||
|
|
|
@ -9,9 +9,9 @@
|
|||
#include <mach-o/dyld.h>
|
||||
|
||||
const struct filedescr _PyImport_DynLoadFiletab[] = {
|
||||
{".so", "rb", C_EXTENSION},
|
||||
{"module.so", "rb", C_EXTENSION},
|
||||
{0, 0}
|
||||
{".so", "rb", C_EXTENSION},
|
||||
{"module.so", "rb", C_EXTENSION},
|
||||
{0, 0}
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -29,86 +29,86 @@ const struct filedescr _PyImport_DynLoadFiletab[] = {
|
|||
#define LINKOPTIONS NSLINKMODULE_OPTION_BINDNOW|NSLINKMODULE_OPTION_RETURN_ON_ERROR
|
||||
#else
|
||||
#define LINKOPTIONS NSLINKMODULE_OPTION_BINDNOW| \
|
||||
NSLINKMODULE_OPTION_RETURN_ON_ERROR|NSLINKMODULE_OPTION_PRIVATE
|
||||
NSLINKMODULE_OPTION_RETURN_ON_ERROR|NSLINKMODULE_OPTION_PRIVATE
|
||||
#endif
|
||||
dl_funcptr _PyImport_GetDynLoadFunc(const char *fqname, const char *shortname,
|
||||
const char *pathname, FILE *fp)
|
||||
const char *pathname, FILE *fp)
|
||||
{
|
||||
dl_funcptr p = NULL;
|
||||
char funcname[258];
|
||||
NSObjectFileImageReturnCode rc;
|
||||
NSObjectFileImage image;
|
||||
NSModule newModule;
|
||||
NSSymbol theSym;
|
||||
const char *errString;
|
||||
char errBuf[512];
|
||||
dl_funcptr p = NULL;
|
||||
char funcname[258];
|
||||
NSObjectFileImageReturnCode rc;
|
||||
NSObjectFileImage image;
|
||||
NSModule newModule;
|
||||
NSSymbol theSym;
|
||||
const char *errString;
|
||||
char errBuf[512];
|
||||
|
||||
PyOS_snprintf(funcname, sizeof(funcname), "_init%.200s", shortname);
|
||||
PyOS_snprintf(funcname, sizeof(funcname), "_init%.200s", shortname);
|
||||
|
||||
#ifdef USE_DYLD_GLOBAL_NAMESPACE
|
||||
if (NSIsSymbolNameDefined(funcname)) {
|
||||
theSym = NSLookupAndBindSymbol(funcname);
|
||||
p = (dl_funcptr)NSAddressOfSymbol(theSym);
|
||||
return p;
|
||||
}
|
||||
if (NSIsSymbolNameDefined(funcname)) {
|
||||
theSym = NSLookupAndBindSymbol(funcname);
|
||||
p = (dl_funcptr)NSAddressOfSymbol(theSym);
|
||||
return p;
|
||||
}
|
||||
#endif
|
||||
rc = NSCreateObjectFileImageFromFile(pathname, &image);
|
||||
switch(rc) {
|
||||
default:
|
||||
case NSObjectFileImageFailure:
|
||||
case NSObjectFileImageFormat:
|
||||
/* for these a message is printed on stderr by dyld */
|
||||
errString = "Can't create object file image";
|
||||
break;
|
||||
case NSObjectFileImageSuccess:
|
||||
errString = NULL;
|
||||
break;
|
||||
case NSObjectFileImageInappropriateFile:
|
||||
errString = "Inappropriate file type for dynamic loading";
|
||||
break;
|
||||
case NSObjectFileImageArch:
|
||||
errString = "Wrong CPU type in object file";
|
||||
break;
|
||||
case NSObjectFileImageAccess:
|
||||
errString = "Can't read object file (no access)";
|
||||
break;
|
||||
}
|
||||
if (errString == NULL) {
|
||||
newModule = NSLinkModule(image, pathname, LINKOPTIONS);
|
||||
if (newModule == NULL) {
|
||||
int errNo;
|
||||
const char *fileName, *moreErrorStr;
|
||||
NSLinkEditErrors c;
|
||||
NSLinkEditError( &c, &errNo, &fileName, &moreErrorStr );
|
||||
PyOS_snprintf(errBuf, 512, "Failure linking new module: %s: %s",
|
||||
fileName, moreErrorStr);
|
||||
errString = errBuf;
|
||||
}
|
||||
}
|
||||
if (errString != NULL) {
|
||||
PyErr_SetString(PyExc_ImportError, errString);
|
||||
return NULL;
|
||||
}
|
||||
rc = NSCreateObjectFileImageFromFile(pathname, &image);
|
||||
switch(rc) {
|
||||
default:
|
||||
case NSObjectFileImageFailure:
|
||||
case NSObjectFileImageFormat:
|
||||
/* for these a message is printed on stderr by dyld */
|
||||
errString = "Can't create object file image";
|
||||
break;
|
||||
case NSObjectFileImageSuccess:
|
||||
errString = NULL;
|
||||
break;
|
||||
case NSObjectFileImageInappropriateFile:
|
||||
errString = "Inappropriate file type for dynamic loading";
|
||||
break;
|
||||
case NSObjectFileImageArch:
|
||||
errString = "Wrong CPU type in object file";
|
||||
break;
|
||||
case NSObjectFileImageAccess:
|
||||
errString = "Can't read object file (no access)";
|
||||
break;
|
||||
}
|
||||
if (errString == NULL) {
|
||||
newModule = NSLinkModule(image, pathname, LINKOPTIONS);
|
||||
if (newModule == NULL) {
|
||||
int errNo;
|
||||
const char *fileName, *moreErrorStr;
|
||||
NSLinkEditErrors c;
|
||||
NSLinkEditError( &c, &errNo, &fileName, &moreErrorStr );
|
||||
PyOS_snprintf(errBuf, 512, "Failure linking new module: %s: %s",
|
||||
fileName, moreErrorStr);
|
||||
errString = errBuf;
|
||||
}
|
||||
}
|
||||
if (errString != NULL) {
|
||||
PyErr_SetString(PyExc_ImportError, errString);
|
||||
return NULL;
|
||||
}
|
||||
#ifdef USE_DYLD_GLOBAL_NAMESPACE
|
||||
if (!NSIsSymbolNameDefined(funcname)) {
|
||||
/* UnlinkModule() isn't implemented in current versions, but calling it does no harm */
|
||||
/* NSUnLinkModule(newModule, FALSE); removed: causes problems for ObjC code */
|
||||
PyErr_Format(PyExc_ImportError,
|
||||
"Loaded module does not contain symbol %.200s",
|
||||
funcname);
|
||||
return NULL;
|
||||
}
|
||||
theSym = NSLookupAndBindSymbol(funcname);
|
||||
if (!NSIsSymbolNameDefined(funcname)) {
|
||||
/* UnlinkModule() isn't implemented in current versions, but calling it does no harm */
|
||||
/* NSUnLinkModule(newModule, FALSE); removed: causes problems for ObjC code */
|
||||
PyErr_Format(PyExc_ImportError,
|
||||
"Loaded module does not contain symbol %.200s",
|
||||
funcname);
|
||||
return NULL;
|
||||
}
|
||||
theSym = NSLookupAndBindSymbol(funcname);
|
||||
#else
|
||||
theSym = NSLookupSymbolInModule(newModule, funcname);
|
||||
if ( theSym == NULL ) {
|
||||
/* NSUnLinkModule(newModule, FALSE); removed: causes problems for ObjC code */
|
||||
PyErr_Format(PyExc_ImportError,
|
||||
"Loaded module does not contain symbol %.200s",
|
||||
funcname);
|
||||
return NULL;
|
||||
}
|
||||
theSym = NSLookupSymbolInModule(newModule, funcname);
|
||||
if ( theSym == NULL ) {
|
||||
/* NSUnLinkModule(newModule, FALSE); removed: causes problems for ObjC code */
|
||||
PyErr_Format(PyExc_ImportError,
|
||||
"Loaded module does not contain symbol %.200s",
|
||||
funcname);
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
p = (dl_funcptr)NSAddressOfSymbol(theSym);
|
||||
return p;
|
||||
p = (dl_funcptr)NSAddressOfSymbol(theSym);
|
||||
return p;
|
||||
}
|
||||
|
|
|
@ -10,37 +10,37 @@
|
|||
|
||||
|
||||
const struct filedescr _PyImport_DynLoadFiletab[] = {
|
||||
{".pyd", "rb", C_EXTENSION},
|
||||
{".dll", "rb", C_EXTENSION},
|
||||
{0, 0}
|
||||
{".pyd", "rb", C_EXTENSION},
|
||||
{".dll", "rb", C_EXTENSION},
|
||||
{0, 0}
|
||||
};
|
||||
|
||||
dl_funcptr _PyImport_GetDynLoadFunc(const char *fqname, const char *shortname,
|
||||
const char *pathname, FILE *fp)
|
||||
const char *pathname, FILE *fp)
|
||||
{
|
||||
dl_funcptr p;
|
||||
APIRET rc;
|
||||
HMODULE hDLL;
|
||||
char failreason[256];
|
||||
char funcname[258];
|
||||
dl_funcptr p;
|
||||
APIRET rc;
|
||||
HMODULE hDLL;
|
||||
char failreason[256];
|
||||
char funcname[258];
|
||||
|
||||
rc = DosLoadModule(failreason,
|
||||
sizeof(failreason),
|
||||
pathname,
|
||||
&hDLL);
|
||||
rc = DosLoadModule(failreason,
|
||||
sizeof(failreason),
|
||||
pathname,
|
||||
&hDLL);
|
||||
|
||||
if (rc != NO_ERROR) {
|
||||
char errBuf[256];
|
||||
PyOS_snprintf(errBuf, sizeof(errBuf),
|
||||
"DLL load failed, rc = %d: %.200s",
|
||||
rc, failreason);
|
||||
PyErr_SetString(PyExc_ImportError, errBuf);
|
||||
return NULL;
|
||||
}
|
||||
if (rc != NO_ERROR) {
|
||||
char errBuf[256];
|
||||
PyOS_snprintf(errBuf, sizeof(errBuf),
|
||||
"DLL load failed, rc = %d: %.200s",
|
||||
rc, failreason);
|
||||
PyErr_SetString(PyExc_ImportError, errBuf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PyOS_snprintf(funcname, sizeof(funcname), "init%.200s", shortname);
|
||||
rc = DosQueryProcAddr(hDLL, 0L, funcname, &p);
|
||||
if (rc != NO_ERROR)
|
||||
p = NULL; /* Signify Failure to Acquire Entrypoint */
|
||||
return p;
|
||||
PyOS_snprintf(funcname, sizeof(funcname), "init%.200s", shortname);
|
||||
rc = DosQueryProcAddr(hDLL, 0L, funcname, &p);
|
||||
if (rc != NO_ERROR)
|
||||
p = NULL; /* Signify Failure to Acquire Entrypoint */
|
||||
return p;
|
||||
}
|
||||
|
|
|
@ -33,111 +33,111 @@
|
|||
|
||||
const struct filedescr _PyImport_DynLoadFiletab[] = {
|
||||
#ifdef __CYGWIN__
|
||||
{".dll", "rb", C_EXTENSION},
|
||||
{"module.dll", "rb", C_EXTENSION},
|
||||
{".dll", "rb", C_EXTENSION},
|
||||
{"module.dll", "rb", C_EXTENSION},
|
||||
#else
|
||||
#if defined(PYOS_OS2) && defined(PYCC_GCC)
|
||||
{".pyd", "rb", C_EXTENSION},
|
||||
{".dll", "rb", C_EXTENSION},
|
||||
{".pyd", "rb", C_EXTENSION},
|
||||
{".dll", "rb", C_EXTENSION},
|
||||
#else
|
||||
#ifdef __VMS
|
||||
{".exe", "rb", C_EXTENSION},
|
||||
{".EXE", "rb", C_EXTENSION},
|
||||
{"module.exe", "rb", C_EXTENSION},
|
||||
{"MODULE.EXE", "rb", C_EXTENSION},
|
||||
{".exe", "rb", C_EXTENSION},
|
||||
{".EXE", "rb", C_EXTENSION},
|
||||
{"module.exe", "rb", C_EXTENSION},
|
||||
{"MODULE.EXE", "rb", C_EXTENSION},
|
||||
#else
|
||||
{".so", "rb", C_EXTENSION},
|
||||
{"module.so", "rb", C_EXTENSION},
|
||||
{".so", "rb", C_EXTENSION},
|
||||
{"module.so", "rb", C_EXTENSION},
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
{0, 0}
|
||||
{0, 0}
|
||||
};
|
||||
|
||||
static struct {
|
||||
dev_t dev;
|
||||
dev_t dev;
|
||||
#ifdef __VMS
|
||||
ino_t ino[3];
|
||||
ino_t ino[3];
|
||||
#else
|
||||
ino_t ino;
|
||||
ino_t ino;
|
||||
#endif
|
||||
void *handle;
|
||||
void *handle;
|
||||
} handles[128];
|
||||
static int nhandles = 0;
|
||||
|
||||
|
||||
dl_funcptr _PyImport_GetDynLoadFunc(const char *fqname, const char *shortname,
|
||||
const char *pathname, FILE *fp)
|
||||
const char *pathname, FILE *fp)
|
||||
{
|
||||
dl_funcptr p;
|
||||
void *handle;
|
||||
char funcname[258];
|
||||
char pathbuf[260];
|
||||
int dlopenflags=0;
|
||||
dl_funcptr p;
|
||||
void *handle;
|
||||
char funcname[258];
|
||||
char pathbuf[260];
|
||||
int dlopenflags=0;
|
||||
|
||||
if (strchr(pathname, '/') == NULL) {
|
||||
/* Prefix bare filename with "./" */
|
||||
PyOS_snprintf(pathbuf, sizeof(pathbuf), "./%-.255s", pathname);
|
||||
pathname = pathbuf;
|
||||
}
|
||||
if (strchr(pathname, '/') == NULL) {
|
||||
/* Prefix bare filename with "./" */
|
||||
PyOS_snprintf(pathbuf, sizeof(pathbuf), "./%-.255s", pathname);
|
||||
pathname = pathbuf;
|
||||
}
|
||||
|
||||
PyOS_snprintf(funcname, sizeof(funcname),
|
||||
LEAD_UNDERSCORE "init%.200s", shortname);
|
||||
PyOS_snprintf(funcname, sizeof(funcname),
|
||||
LEAD_UNDERSCORE "init%.200s", shortname);
|
||||
|
||||
if (fp != NULL) {
|
||||
int i;
|
||||
struct stat statb;
|
||||
fstat(fileno(fp), &statb);
|
||||
for (i = 0; i < nhandles; i++) {
|
||||
if (statb.st_dev == handles[i].dev &&
|
||||
statb.st_ino == handles[i].ino) {
|
||||
p = (dl_funcptr) dlsym(handles[i].handle,
|
||||
funcname);
|
||||
return p;
|
||||
}
|
||||
}
|
||||
if (nhandles < 128) {
|
||||
handles[nhandles].dev = statb.st_dev;
|
||||
if (fp != NULL) {
|
||||
int i;
|
||||
struct stat statb;
|
||||
fstat(fileno(fp), &statb);
|
||||
for (i = 0; i < nhandles; i++) {
|
||||
if (statb.st_dev == handles[i].dev &&
|
||||
statb.st_ino == handles[i].ino) {
|
||||
p = (dl_funcptr) dlsym(handles[i].handle,
|
||||
funcname);
|
||||
return p;
|
||||
}
|
||||
}
|
||||
if (nhandles < 128) {
|
||||
handles[nhandles].dev = statb.st_dev;
|
||||
#ifdef __VMS
|
||||
handles[nhandles].ino[0] = statb.st_ino[0];
|
||||
handles[nhandles].ino[1] = statb.st_ino[1];
|
||||
handles[nhandles].ino[2] = statb.st_ino[2];
|
||||
handles[nhandles].ino[0] = statb.st_ino[0];
|
||||
handles[nhandles].ino[1] = statb.st_ino[1];
|
||||
handles[nhandles].ino[2] = statb.st_ino[2];
|
||||
#else
|
||||
handles[nhandles].ino = statb.st_ino;
|
||||
handles[nhandles].ino = statb.st_ino;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if !(defined(PYOS_OS2) && defined(PYCC_GCC))
|
||||
dlopenflags = PyThreadState_GET()->interp->dlopenflags;
|
||||
dlopenflags = PyThreadState_GET()->interp->dlopenflags;
|
||||
#endif
|
||||
|
||||
if (Py_VerboseFlag)
|
||||
PySys_WriteStderr("dlopen(\"%s\", %x);\n", pathname,
|
||||
dlopenflags);
|
||||
if (Py_VerboseFlag)
|
||||
PySys_WriteStderr("dlopen(\"%s\", %x);\n", pathname,
|
||||
dlopenflags);
|
||||
|
||||
#ifdef __VMS
|
||||
/* VMS currently don't allow a pathname, use a logical name instead */
|
||||
/* Concatenate 'python_module_' and shortname */
|
||||
/* so "import vms.bar" will use the logical python_module_bar */
|
||||
/* As C module use only one name space this is probably not a */
|
||||
/* important limitation */
|
||||
PyOS_snprintf(pathbuf, sizeof(pathbuf), "python_module_%-.200s",
|
||||
shortname);
|
||||
pathname = pathbuf;
|
||||
/* VMS currently don't allow a pathname, use a logical name instead */
|
||||
/* Concatenate 'python_module_' and shortname */
|
||||
/* so "import vms.bar" will use the logical python_module_bar */
|
||||
/* As C module use only one name space this is probably not a */
|
||||
/* important limitation */
|
||||
PyOS_snprintf(pathbuf, sizeof(pathbuf), "python_module_%-.200s",
|
||||
shortname);
|
||||
pathname = pathbuf;
|
||||
#endif
|
||||
|
||||
handle = dlopen(pathname, dlopenflags);
|
||||
handle = dlopen(pathname, dlopenflags);
|
||||
|
||||
if (handle == NULL) {
|
||||
const char *error = dlerror();
|
||||
if (error == NULL)
|
||||
error = "unknown dlopen() error";
|
||||
PyErr_SetString(PyExc_ImportError, error);
|
||||
return NULL;
|
||||
}
|
||||
if (fp != NULL && nhandles < 128)
|
||||
handles[nhandles++].handle = handle;
|
||||
p = (dl_funcptr) dlsym(handle, funcname);
|
||||
return p;
|
||||
if (handle == NULL) {
|
||||
const char *error = dlerror();
|
||||
if (error == NULL)
|
||||
error = "unknown dlopen() error";
|
||||
PyErr_SetString(PyExc_ImportError, error);
|
||||
return NULL;
|
||||
}
|
||||
if (fp != NULL && nhandles < 128)
|
||||
handles[nhandles++].handle = handle;
|
||||
p = (dl_funcptr) dlsym(handle, funcname);
|
||||
return p;
|
||||
}
|
||||
|
|
|
@ -17,11 +17,11 @@ void _Py_DeactivateActCtx(ULONG_PTR cookie);
|
|||
|
||||
const struct filedescr _PyImport_DynLoadFiletab[] = {
|
||||
#ifdef _DEBUG
|
||||
{"_d.pyd", "rb", C_EXTENSION},
|
||||
{"_d.pyd", "rb", C_EXTENSION},
|
||||
#else
|
||||
{".pyd", "rb", C_EXTENSION},
|
||||
{".pyd", "rb", C_EXTENSION},
|
||||
#endif
|
||||
{0, 0}
|
||||
{0, 0}
|
||||
};
|
||||
|
||||
|
||||
|
@ -29,18 +29,18 @@ const struct filedescr _PyImport_DynLoadFiletab[] = {
|
|||
C RTL implementations */
|
||||
|
||||
static int strcasecmp (char *string1, char *string2)
|
||||
{
|
||||
int first, second;
|
||||
{
|
||||
int first, second;
|
||||
|
||||
do {
|
||||
first = tolower(*string1);
|
||||
second = tolower(*string2);
|
||||
string1++;
|
||||
string2++;
|
||||
} while (first && first == second);
|
||||
do {
|
||||
first = tolower(*string1);
|
||||
second = tolower(*string2);
|
||||
string1++;
|
||||
string2++;
|
||||
} while (first && first == second);
|
||||
|
||||
return (first - second);
|
||||
}
|
||||
return (first - second);
|
||||
}
|
||||
|
||||
|
||||
/* Function to return the name of the "python" DLL that the supplied module
|
||||
|
@ -66,209 +66,209 @@ static int strcasecmp (char *string1, char *string2)
|
|||
|
||||
static char *GetPythonImport (HINSTANCE hModule)
|
||||
{
|
||||
unsigned char *dllbase, *import_data, *import_name;
|
||||
DWORD pe_offset, opt_offset;
|
||||
WORD opt_magic;
|
||||
int num_dict_off, import_off;
|
||||
unsigned char *dllbase, *import_data, *import_name;
|
||||
DWORD pe_offset, opt_offset;
|
||||
WORD opt_magic;
|
||||
int num_dict_off, import_off;
|
||||
|
||||
/* Safety check input */
|
||||
if (hModule == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
/* Safety check input */
|
||||
if (hModule == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Module instance is also the base load address. First portion of
|
||||
memory is the MS-DOS loader, which holds the offset to the PE
|
||||
header (from the load base) at 0x3C */
|
||||
dllbase = (unsigned char *)hModule;
|
||||
pe_offset = DWORD_AT(dllbase + 0x3C);
|
||||
/* Module instance is also the base load address. First portion of
|
||||
memory is the MS-DOS loader, which holds the offset to the PE
|
||||
header (from the load base) at 0x3C */
|
||||
dllbase = (unsigned char *)hModule;
|
||||
pe_offset = DWORD_AT(dllbase + 0x3C);
|
||||
|
||||
/* The PE signature must be "PE\0\0" */
|
||||
if (memcmp(dllbase+pe_offset,"PE\0\0",4)) {
|
||||
return NULL;
|
||||
}
|
||||
/* The PE signature must be "PE\0\0" */
|
||||
if (memcmp(dllbase+pe_offset,"PE\0\0",4)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Following the PE signature is the standard COFF header (20
|
||||
bytes) and then the optional header. The optional header starts
|
||||
with a magic value of 0x10B for PE32 or 0x20B for PE32+ (PE32+
|
||||
uses 64-bits for some fields). It might also be 0x107 for a ROM
|
||||
image, but we don't process that here.
|
||||
/* Following the PE signature is the standard COFF header (20
|
||||
bytes) and then the optional header. The optional header starts
|
||||
with a magic value of 0x10B for PE32 or 0x20B for PE32+ (PE32+
|
||||
uses 64-bits for some fields). It might also be 0x107 for a ROM
|
||||
image, but we don't process that here.
|
||||
|
||||
The optional header ends with a data dictionary that directly
|
||||
points to certain types of data, among them the import entries
|
||||
(in the second table entry). Based on the header type, we
|
||||
determine offsets for the data dictionary count and the entry
|
||||
within the dictionary pointing to the imports. */
|
||||
The optional header ends with a data dictionary that directly
|
||||
points to certain types of data, among them the import entries
|
||||
(in the second table entry). Based on the header type, we
|
||||
determine offsets for the data dictionary count and the entry
|
||||
within the dictionary pointing to the imports. */
|
||||
|
||||
opt_offset = pe_offset + 4 + 20;
|
||||
opt_magic = WORD_AT(dllbase+opt_offset);
|
||||
if (opt_magic == 0x10B) {
|
||||
/* PE32 */
|
||||
num_dict_off = 92;
|
||||
import_off = 104;
|
||||
} else if (opt_magic == 0x20B) {
|
||||
/* PE32+ */
|
||||
num_dict_off = 108;
|
||||
import_off = 120;
|
||||
} else {
|
||||
/* Unsupported */
|
||||
return NULL;
|
||||
}
|
||||
opt_offset = pe_offset + 4 + 20;
|
||||
opt_magic = WORD_AT(dllbase+opt_offset);
|
||||
if (opt_magic == 0x10B) {
|
||||
/* PE32 */
|
||||
num_dict_off = 92;
|
||||
import_off = 104;
|
||||
} else if (opt_magic == 0x20B) {
|
||||
/* PE32+ */
|
||||
num_dict_off = 108;
|
||||
import_off = 120;
|
||||
} else {
|
||||
/* Unsupported */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Now if an import table exists, offset to it and walk the list of
|
||||
imports. The import table is an array (ending when an entry has
|
||||
empty values) of structures (20 bytes each), which contains (at
|
||||
offset 12) a relative address (to the module base) at which a
|
||||
string constant holding the import name is located. */
|
||||
/* Now if an import table exists, offset to it and walk the list of
|
||||
imports. The import table is an array (ending when an entry has
|
||||
empty values) of structures (20 bytes each), which contains (at
|
||||
offset 12) a relative address (to the module base) at which a
|
||||
string constant holding the import name is located. */
|
||||
|
||||
if (DWORD_AT(dllbase + opt_offset + num_dict_off) >= 2) {
|
||||
/* We have at least 2 tables - the import table is the second
|
||||
one. But still it may be that the table size is zero */
|
||||
if (0 == DWORD_AT(dllbase + opt_offset + import_off + sizeof(DWORD)))
|
||||
return NULL;
|
||||
import_data = dllbase + DWORD_AT(dllbase +
|
||||
opt_offset +
|
||||
import_off);
|
||||
while (DWORD_AT(import_data)) {
|
||||
import_name = dllbase + DWORD_AT(import_data+12);
|
||||
if (strlen(import_name) >= 6 &&
|
||||
!strncmp(import_name,"python",6)) {
|
||||
char *pch;
|
||||
if (DWORD_AT(dllbase + opt_offset + num_dict_off) >= 2) {
|
||||
/* We have at least 2 tables - the import table is the second
|
||||
one. But still it may be that the table size is zero */
|
||||
if (0 == DWORD_AT(dllbase + opt_offset + import_off + sizeof(DWORD)))
|
||||
return NULL;
|
||||
import_data = dllbase + DWORD_AT(dllbase +
|
||||
opt_offset +
|
||||
import_off);
|
||||
while (DWORD_AT(import_data)) {
|
||||
import_name = dllbase + DWORD_AT(import_data+12);
|
||||
if (strlen(import_name) >= 6 &&
|
||||
!strncmp(import_name,"python",6)) {
|
||||
char *pch;
|
||||
|
||||
/* Ensure python prefix is followed only
|
||||
by numbers to the end of the basename */
|
||||
pch = import_name + 6;
|
||||
/* Ensure python prefix is followed only
|
||||
by numbers to the end of the basename */
|
||||
pch = import_name + 6;
|
||||
#ifdef _DEBUG
|
||||
while (*pch && pch[0] != '_' && pch[1] != 'd' && pch[2] != '.') {
|
||||
while (*pch && pch[0] != '_' && pch[1] != 'd' && pch[2] != '.') {
|
||||
#else
|
||||
while (*pch && *pch != '.') {
|
||||
while (*pch && *pch != '.') {
|
||||
#endif
|
||||
if (*pch >= '0' && *pch <= '9') {
|
||||
pch++;
|
||||
} else {
|
||||
pch = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (pch) {
|
||||
/* Found it - return the name */
|
||||
return import_name;
|
||||
}
|
||||
}
|
||||
import_data += 20;
|
||||
}
|
||||
}
|
||||
if (*pch >= '0' && *pch <= '9') {
|
||||
pch++;
|
||||
} else {
|
||||
pch = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
if (pch) {
|
||||
/* Found it - return the name */
|
||||
return import_name;
|
||||
}
|
||||
}
|
||||
import_data += 20;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
dl_funcptr _PyImport_GetDynLoadFunc(const char *fqname, const char *shortname,
|
||||
const char *pathname, FILE *fp)
|
||||
const char *pathname, FILE *fp)
|
||||
{
|
||||
dl_funcptr p;
|
||||
char funcname[258], *import_python;
|
||||
dl_funcptr p;
|
||||
char funcname[258], *import_python;
|
||||
|
||||
PyOS_snprintf(funcname, sizeof(funcname), "init%.200s", shortname);
|
||||
PyOS_snprintf(funcname, sizeof(funcname), "init%.200s", shortname);
|
||||
|
||||
{
|
||||
HINSTANCE hDLL = NULL;
|
||||
char pathbuf[260];
|
||||
LPTSTR dummy;
|
||||
unsigned int old_mode;
|
||||
ULONG_PTR cookie = 0;
|
||||
/* We use LoadLibraryEx so Windows looks for dependent DLLs
|
||||
in directory of pathname first. However, Windows95
|
||||
can sometimes not work correctly unless the absolute
|
||||
path is used. If GetFullPathName() fails, the LoadLibrary
|
||||
will certainly fail too, so use its error code */
|
||||
{
|
||||
HINSTANCE hDLL = NULL;
|
||||
char pathbuf[260];
|
||||
LPTSTR dummy;
|
||||
unsigned int old_mode;
|
||||
ULONG_PTR cookie = 0;
|
||||
/* We use LoadLibraryEx so Windows looks for dependent DLLs
|
||||
in directory of pathname first. However, Windows95
|
||||
can sometimes not work correctly unless the absolute
|
||||
path is used. If GetFullPathName() fails, the LoadLibrary
|
||||
will certainly fail too, so use its error code */
|
||||
|
||||
/* Don't display a message box when Python can't load a DLL */
|
||||
old_mode = SetErrorMode(SEM_FAILCRITICALERRORS);
|
||||
/* Don't display a message box when Python can't load a DLL */
|
||||
old_mode = SetErrorMode(SEM_FAILCRITICALERRORS);
|
||||
|
||||
if (GetFullPathName(pathname,
|
||||
sizeof(pathbuf),
|
||||
pathbuf,
|
||||
&dummy)) {
|
||||
ULONG_PTR cookie = _Py_ActivateActCtx();
|
||||
/* XXX This call doesn't exist in Windows CE */
|
||||
hDLL = LoadLibraryEx(pathname, NULL,
|
||||
LOAD_WITH_ALTERED_SEARCH_PATH);
|
||||
_Py_DeactivateActCtx(cookie);
|
||||
}
|
||||
if (GetFullPathName(pathname,
|
||||
sizeof(pathbuf),
|
||||
pathbuf,
|
||||
&dummy)) {
|
||||
ULONG_PTR cookie = _Py_ActivateActCtx();
|
||||
/* XXX This call doesn't exist in Windows CE */
|
||||
hDLL = LoadLibraryEx(pathname, NULL,
|
||||
LOAD_WITH_ALTERED_SEARCH_PATH);
|
||||
_Py_DeactivateActCtx(cookie);
|
||||
}
|
||||
|
||||
/* restore old error mode settings */
|
||||
SetErrorMode(old_mode);
|
||||
/* restore old error mode settings */
|
||||
SetErrorMode(old_mode);
|
||||
|
||||
if (hDLL==NULL){
|
||||
char errBuf[256];
|
||||
unsigned int errorCode;
|
||||
if (hDLL==NULL){
|
||||
char errBuf[256];
|
||||
unsigned int errorCode;
|
||||
|
||||
/* Get an error string from Win32 error code */
|
||||
char theInfo[256]; /* Pointer to error text
|
||||
from system */
|
||||
int theLength; /* Length of error text */
|
||||
/* Get an error string from Win32 error code */
|
||||
char theInfo[256]; /* Pointer to error text
|
||||
from system */
|
||||
int theLength; /* Length of error text */
|
||||
|
||||
errorCode = GetLastError();
|
||||
errorCode = GetLastError();
|
||||
|
||||
theLength = FormatMessage(
|
||||
FORMAT_MESSAGE_FROM_SYSTEM |
|
||||
FORMAT_MESSAGE_IGNORE_INSERTS, /* flags */
|
||||
NULL, /* message source */
|
||||
errorCode, /* the message (error) ID */
|
||||
0, /* default language environment */
|
||||
(LPTSTR) theInfo, /* the buffer */
|
||||
sizeof(theInfo), /* the buffer size */
|
||||
NULL); /* no additional format args. */
|
||||
theLength = FormatMessage(
|
||||
FORMAT_MESSAGE_FROM_SYSTEM |
|
||||
FORMAT_MESSAGE_IGNORE_INSERTS, /* flags */
|
||||
NULL, /* message source */
|
||||
errorCode, /* the message (error) ID */
|
||||
0, /* default language environment */
|
||||
(LPTSTR) theInfo, /* the buffer */
|
||||
sizeof(theInfo), /* the buffer size */
|
||||
NULL); /* no additional format args. */
|
||||
|
||||
/* Problem: could not get the error message.
|
||||
This should not happen if called correctly. */
|
||||
if (theLength == 0) {
|
||||
PyOS_snprintf(errBuf, sizeof(errBuf),
|
||||
"DLL load failed with error code %d",
|
||||
errorCode);
|
||||
} else {
|
||||
size_t len;
|
||||
/* For some reason a \r\n
|
||||
is appended to the text */
|
||||
if (theLength >= 2 &&
|
||||
theInfo[theLength-2] == '\r' &&
|
||||
theInfo[theLength-1] == '\n') {
|
||||
theLength -= 2;
|
||||
theInfo[theLength] = '\0';
|
||||
}
|
||||
strcpy(errBuf, "DLL load failed: ");
|
||||
len = strlen(errBuf);
|
||||
strncpy(errBuf+len, theInfo,
|
||||
sizeof(errBuf)-len);
|
||||
errBuf[sizeof(errBuf)-1] = '\0';
|
||||
}
|
||||
PyErr_SetString(PyExc_ImportError, errBuf);
|
||||
return NULL;
|
||||
} else {
|
||||
char buffer[256];
|
||||
/* Problem: could not get the error message.
|
||||
This should not happen if called correctly. */
|
||||
if (theLength == 0) {
|
||||
PyOS_snprintf(errBuf, sizeof(errBuf),
|
||||
"DLL load failed with error code %d",
|
||||
errorCode);
|
||||
} else {
|
||||
size_t len;
|
||||
/* For some reason a \r\n
|
||||
is appended to the text */
|
||||
if (theLength >= 2 &&
|
||||
theInfo[theLength-2] == '\r' &&
|
||||
theInfo[theLength-1] == '\n') {
|
||||
theLength -= 2;
|
||||
theInfo[theLength] = '\0';
|
||||
}
|
||||
strcpy(errBuf, "DLL load failed: ");
|
||||
len = strlen(errBuf);
|
||||
strncpy(errBuf+len, theInfo,
|
||||
sizeof(errBuf)-len);
|
||||
errBuf[sizeof(errBuf)-1] = '\0';
|
||||
}
|
||||
PyErr_SetString(PyExc_ImportError, errBuf);
|
||||
return NULL;
|
||||
} else {
|
||||
char buffer[256];
|
||||
|
||||
#ifdef _DEBUG
|
||||
PyOS_snprintf(buffer, sizeof(buffer), "python%d%d_d.dll",
|
||||
PyOS_snprintf(buffer, sizeof(buffer), "python%d%d_d.dll",
|
||||
#else
|
||||
PyOS_snprintf(buffer, sizeof(buffer), "python%d%d.dll",
|
||||
PyOS_snprintf(buffer, sizeof(buffer), "python%d%d.dll",
|
||||
#endif
|
||||
PY_MAJOR_VERSION,PY_MINOR_VERSION);
|
||||
import_python = GetPythonImport(hDLL);
|
||||
PY_MAJOR_VERSION,PY_MINOR_VERSION);
|
||||
import_python = GetPythonImport(hDLL);
|
||||
|
||||
if (import_python &&
|
||||
strcasecmp(buffer,import_python)) {
|
||||
PyOS_snprintf(buffer, sizeof(buffer),
|
||||
"Module use of %.150s conflicts "
|
||||
"with this version of Python.",
|
||||
import_python);
|
||||
PyErr_SetString(PyExc_ImportError,buffer);
|
||||
FreeLibrary(hDLL);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
p = GetProcAddress(hDLL, funcname);
|
||||
}
|
||||
if (import_python &&
|
||||
strcasecmp(buffer,import_python)) {
|
||||
PyOS_snprintf(buffer, sizeof(buffer),
|
||||
"Module use of %.150s conflicts "
|
||||
"with this version of Python.",
|
||||
import_python);
|
||||
PyErr_SetString(PyExc_ImportError,buffer);
|
||||
FreeLibrary(hDLL);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
p = GetProcAddress(hDLL, funcname);
|
||||
}
|
||||
|
||||
return p;
|
||||
return p;
|
||||
}
|
||||
|
|
1082
Python/errors.c
1082
Python/errors.c
File diff suppressed because it is too large
Load diff
|
@ -12,24 +12,24 @@
|
|||
the appropriate bytes from M___main__.c. */
|
||||
|
||||
static unsigned char M___hello__[] = {
|
||||
99,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,
|
||||
0,115,9,0,0,0,100,0,0,71,72,100,1,0,83,40,
|
||||
2,0,0,0,115,14,0,0,0,72,101,108,108,111,32,119,
|
||||
111,114,108,100,46,46,46,78,40,0,0,0,0,40,0,0,
|
||||
0,0,40,0,0,0,0,40,0,0,0,0,115,8,0,0,
|
||||
0,104,101,108,108,111,46,112,121,115,1,0,0,0,63,1,
|
||||
0,0,0,115,0,0,0,0,
|
||||
99,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,
|
||||
0,115,9,0,0,0,100,0,0,71,72,100,1,0,83,40,
|
||||
2,0,0,0,115,14,0,0,0,72,101,108,108,111,32,119,
|
||||
111,114,108,100,46,46,46,78,40,0,0,0,0,40,0,0,
|
||||
0,0,40,0,0,0,0,40,0,0,0,0,115,8,0,0,
|
||||
0,104,101,108,108,111,46,112,121,115,1,0,0,0,63,1,
|
||||
0,0,0,115,0,0,0,0,
|
||||
};
|
||||
|
||||
#define SIZE (int)sizeof(M___hello__)
|
||||
|
||||
static struct _frozen _PyImport_FrozenModules[] = {
|
||||
/* Test module */
|
||||
{"__hello__", M___hello__, SIZE},
|
||||
/* Test package (negative size indicates package-ness) */
|
||||
{"__phello__", M___hello__, -SIZE},
|
||||
{"__phello__.spam", M___hello__, SIZE},
|
||||
{0, 0, 0} /* sentinel */
|
||||
/* Test module */
|
||||
{"__hello__", M___hello__, SIZE},
|
||||
/* Test package (negative size indicates package-ness) */
|
||||
{"__phello__", M___hello__, -SIZE},
|
||||
{"__phello__.spam", M___hello__, SIZE},
|
||||
{0, 0, 0} /* sentinel */
|
||||
};
|
||||
|
||||
/* Embedding apps may change this pointer to point to their favorite
|
||||
|
|
|
@ -14,55 +14,55 @@ extern int PyInitFrozenExtensions(void);
|
|||
int
|
||||
Py_FrozenMain(int argc, char **argv)
|
||||
{
|
||||
char *p;
|
||||
int n, sts;
|
||||
int inspect = 0;
|
||||
int unbuffered = 0;
|
||||
char *p;
|
||||
int n, sts;
|
||||
int inspect = 0;
|
||||
int unbuffered = 0;
|
||||
|
||||
Py_FrozenFlag = 1; /* Suppress errors from getpath.c */
|
||||
Py_FrozenFlag = 1; /* Suppress errors from getpath.c */
|
||||
|
||||
if ((p = Py_GETENV("PYTHONINSPECT")) && *p != '\0')
|
||||
inspect = 1;
|
||||
if ((p = Py_GETENV("PYTHONUNBUFFERED")) && *p != '\0')
|
||||
unbuffered = 1;
|
||||
if ((p = Py_GETENV("PYTHONINSPECT")) && *p != '\0')
|
||||
inspect = 1;
|
||||
if ((p = Py_GETENV("PYTHONUNBUFFERED")) && *p != '\0')
|
||||
unbuffered = 1;
|
||||
|
||||
if (unbuffered) {
|
||||
setbuf(stdin, (char *)NULL);
|
||||
setbuf(stdout, (char *)NULL);
|
||||
setbuf(stderr, (char *)NULL);
|
||||
}
|
||||
if (unbuffered) {
|
||||
setbuf(stdin, (char *)NULL);
|
||||
setbuf(stdout, (char *)NULL);
|
||||
setbuf(stderr, (char *)NULL);
|
||||
}
|
||||
|
||||
#ifdef MS_WINDOWS
|
||||
PyInitFrozenExtensions();
|
||||
PyInitFrozenExtensions();
|
||||
#endif /* MS_WINDOWS */
|
||||
Py_SetProgramName(argv[0]);
|
||||
Py_Initialize();
|
||||
Py_SetProgramName(argv[0]);
|
||||
Py_Initialize();
|
||||
#ifdef MS_WINDOWS
|
||||
PyWinFreeze_ExeInit();
|
||||
PyWinFreeze_ExeInit();
|
||||
#endif
|
||||
|
||||
if (Py_VerboseFlag)
|
||||
fprintf(stderr, "Python %s\n%s\n",
|
||||
Py_GetVersion(), Py_GetCopyright());
|
||||
if (Py_VerboseFlag)
|
||||
fprintf(stderr, "Python %s\n%s\n",
|
||||
Py_GetVersion(), Py_GetCopyright());
|
||||
|
||||
PySys_SetArgv(argc, argv);
|
||||
PySys_SetArgv(argc, argv);
|
||||
|
||||
n = PyImport_ImportFrozenModule("__main__");
|
||||
if (n == 0)
|
||||
Py_FatalError("__main__ not frozen");
|
||||
if (n < 0) {
|
||||
PyErr_Print();
|
||||
sts = 1;
|
||||
}
|
||||
else
|
||||
sts = 0;
|
||||
n = PyImport_ImportFrozenModule("__main__");
|
||||
if (n == 0)
|
||||
Py_FatalError("__main__ not frozen");
|
||||
if (n < 0) {
|
||||
PyErr_Print();
|
||||
sts = 1;
|
||||
}
|
||||
else
|
||||
sts = 0;
|
||||
|
||||
if (inspect && isatty((int)fileno(stdin)))
|
||||
sts = PyRun_AnyFile(stdin, "<stdin>") != 0;
|
||||
if (inspect && isatty((int)fileno(stdin)))
|
||||
sts = PyRun_AnyFile(stdin, "<stdin>") != 0;
|
||||
|
||||
#ifdef MS_WINDOWS
|
||||
PyWinFreeze_ExeTerm();
|
||||
PyWinFreeze_ExeTerm();
|
||||
#endif
|
||||
Py_Finalize();
|
||||
return sts;
|
||||
Py_Finalize();
|
||||
return sts;
|
||||
}
|
||||
|
|
206
Python/future.c
206
Python/future.c
|
@ -14,129 +14,129 @@
|
|||
static int
|
||||
future_check_features(PyFutureFeatures *ff, stmt_ty s, const char *filename)
|
||||
{
|
||||
int i;
|
||||
asdl_seq *names;
|
||||
int i;
|
||||
asdl_seq *names;
|
||||
|
||||
assert(s->kind == ImportFrom_kind);
|
||||
assert(s->kind == ImportFrom_kind);
|
||||
|
||||
names = s->v.ImportFrom.names;
|
||||
for (i = 0; i < asdl_seq_LEN(names); i++) {
|
||||
alias_ty name = (alias_ty)asdl_seq_GET(names, i);
|
||||
const char *feature = PyString_AsString(name->name);
|
||||
if (!feature)
|
||||
return 0;
|
||||
if (strcmp(feature, FUTURE_NESTED_SCOPES) == 0) {
|
||||
continue;
|
||||
} else if (strcmp(feature, FUTURE_GENERATORS) == 0) {
|
||||
continue;
|
||||
} else if (strcmp(feature, FUTURE_DIVISION) == 0) {
|
||||
ff->ff_features |= CO_FUTURE_DIVISION;
|
||||
} else if (strcmp(feature, FUTURE_ABSOLUTE_IMPORT) == 0) {
|
||||
ff->ff_features |= CO_FUTURE_ABSOLUTE_IMPORT;
|
||||
} else if (strcmp(feature, FUTURE_WITH_STATEMENT) == 0) {
|
||||
ff->ff_features |= CO_FUTURE_WITH_STATEMENT;
|
||||
} else if (strcmp(feature, FUTURE_PRINT_FUNCTION) == 0) {
|
||||
ff->ff_features |= CO_FUTURE_PRINT_FUNCTION;
|
||||
} else if (strcmp(feature, FUTURE_UNICODE_LITERALS) == 0) {
|
||||
ff->ff_features |= CO_FUTURE_UNICODE_LITERALS;
|
||||
} else if (strcmp(feature, "braces") == 0) {
|
||||
PyErr_SetString(PyExc_SyntaxError,
|
||||
"not a chance");
|
||||
PyErr_SyntaxLocation(filename, s->lineno);
|
||||
return 0;
|
||||
} else {
|
||||
PyErr_Format(PyExc_SyntaxError,
|
||||
UNDEFINED_FUTURE_FEATURE, feature);
|
||||
PyErr_SyntaxLocation(filename, s->lineno);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
names = s->v.ImportFrom.names;
|
||||
for (i = 0; i < asdl_seq_LEN(names); i++) {
|
||||
alias_ty name = (alias_ty)asdl_seq_GET(names, i);
|
||||
const char *feature = PyString_AsString(name->name);
|
||||
if (!feature)
|
||||
return 0;
|
||||
if (strcmp(feature, FUTURE_NESTED_SCOPES) == 0) {
|
||||
continue;
|
||||
} else if (strcmp(feature, FUTURE_GENERATORS) == 0) {
|
||||
continue;
|
||||
} else if (strcmp(feature, FUTURE_DIVISION) == 0) {
|
||||
ff->ff_features |= CO_FUTURE_DIVISION;
|
||||
} else if (strcmp(feature, FUTURE_ABSOLUTE_IMPORT) == 0) {
|
||||
ff->ff_features |= CO_FUTURE_ABSOLUTE_IMPORT;
|
||||
} else if (strcmp(feature, FUTURE_WITH_STATEMENT) == 0) {
|
||||
ff->ff_features |= CO_FUTURE_WITH_STATEMENT;
|
||||
} else if (strcmp(feature, FUTURE_PRINT_FUNCTION) == 0) {
|
||||
ff->ff_features |= CO_FUTURE_PRINT_FUNCTION;
|
||||
} else if (strcmp(feature, FUTURE_UNICODE_LITERALS) == 0) {
|
||||
ff->ff_features |= CO_FUTURE_UNICODE_LITERALS;
|
||||
} else if (strcmp(feature, "braces") == 0) {
|
||||
PyErr_SetString(PyExc_SyntaxError,
|
||||
"not a chance");
|
||||
PyErr_SyntaxLocation(filename, s->lineno);
|
||||
return 0;
|
||||
} else {
|
||||
PyErr_Format(PyExc_SyntaxError,
|
||||
UNDEFINED_FUTURE_FEATURE, feature);
|
||||
PyErr_SyntaxLocation(filename, s->lineno);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
future_parse(PyFutureFeatures *ff, mod_ty mod, const char *filename)
|
||||
{
|
||||
int i, found_docstring = 0, done = 0, prev_line = 0;
|
||||
int i, found_docstring = 0, done = 0, prev_line = 0;
|
||||
|
||||
static PyObject *future;
|
||||
if (!future) {
|
||||
future = PyString_InternFromString("__future__");
|
||||
if (!future)
|
||||
return 0;
|
||||
}
|
||||
static PyObject *future;
|
||||
if (!future) {
|
||||
future = PyString_InternFromString("__future__");
|
||||
if (!future)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(mod->kind == Module_kind || mod->kind == Interactive_kind))
|
||||
return 1;
|
||||
if (!(mod->kind == Module_kind || mod->kind == Interactive_kind))
|
||||
return 1;
|
||||
|
||||
/* A subsequent pass will detect future imports that don't
|
||||
appear at the beginning of the file. There's one case,
|
||||
however, that is easier to handle here: A series of imports
|
||||
joined by semi-colons, where the first import is a future
|
||||
statement but some subsequent import has the future form
|
||||
but is preceded by a regular import.
|
||||
*/
|
||||
|
||||
/* A subsequent pass will detect future imports that don't
|
||||
appear at the beginning of the file. There's one case,
|
||||
however, that is easier to handle here: A series of imports
|
||||
joined by semi-colons, where the first import is a future
|
||||
statement but some subsequent import has the future form
|
||||
but is preceded by a regular import.
|
||||
*/
|
||||
|
||||
for (i = 0; i < asdl_seq_LEN(mod->v.Module.body); i++) {
|
||||
stmt_ty s = (stmt_ty)asdl_seq_GET(mod->v.Module.body, i);
|
||||
|
||||
if (done && s->lineno > prev_line)
|
||||
return 1;
|
||||
prev_line = s->lineno;
|
||||
for (i = 0; i < asdl_seq_LEN(mod->v.Module.body); i++) {
|
||||
stmt_ty s = (stmt_ty)asdl_seq_GET(mod->v.Module.body, i);
|
||||
|
||||
/* The tests below will return from this function unless it is
|
||||
still possible to find a future statement. The only things
|
||||
that can precede a future statement are another future
|
||||
statement and a doc string.
|
||||
*/
|
||||
if (done && s->lineno > prev_line)
|
||||
return 1;
|
||||
prev_line = s->lineno;
|
||||
|
||||
if (s->kind == ImportFrom_kind) {
|
||||
if (s->v.ImportFrom.module == future) {
|
||||
if (done) {
|
||||
PyErr_SetString(PyExc_SyntaxError,
|
||||
ERR_LATE_FUTURE);
|
||||
PyErr_SyntaxLocation(filename,
|
||||
s->lineno);
|
||||
return 0;
|
||||
}
|
||||
if (!future_check_features(ff, s, filename))
|
||||
return 0;
|
||||
ff->ff_lineno = s->lineno;
|
||||
}
|
||||
else
|
||||
done = 1;
|
||||
}
|
||||
else if (s->kind == Expr_kind && !found_docstring) {
|
||||
expr_ty e = s->v.Expr.value;
|
||||
if (e->kind != Str_kind)
|
||||
done = 1;
|
||||
else
|
||||
found_docstring = 1;
|
||||
}
|
||||
else
|
||||
done = 1;
|
||||
}
|
||||
return 1;
|
||||
/* The tests below will return from this function unless it is
|
||||
still possible to find a future statement. The only things
|
||||
that can precede a future statement are another future
|
||||
statement and a doc string.
|
||||
*/
|
||||
|
||||
if (s->kind == ImportFrom_kind) {
|
||||
if (s->v.ImportFrom.module == future) {
|
||||
if (done) {
|
||||
PyErr_SetString(PyExc_SyntaxError,
|
||||
ERR_LATE_FUTURE);
|
||||
PyErr_SyntaxLocation(filename,
|
||||
s->lineno);
|
||||
return 0;
|
||||
}
|
||||
if (!future_check_features(ff, s, filename))
|
||||
return 0;
|
||||
ff->ff_lineno = s->lineno;
|
||||
}
|
||||
else
|
||||
done = 1;
|
||||
}
|
||||
else if (s->kind == Expr_kind && !found_docstring) {
|
||||
expr_ty e = s->v.Expr.value;
|
||||
if (e->kind != Str_kind)
|
||||
done = 1;
|
||||
else
|
||||
found_docstring = 1;
|
||||
}
|
||||
else
|
||||
done = 1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
PyFutureFeatures *
|
||||
PyFuture_FromAST(mod_ty mod, const char *filename)
|
||||
{
|
||||
PyFutureFeatures *ff;
|
||||
PyFutureFeatures *ff;
|
||||
|
||||
ff = (PyFutureFeatures *)PyObject_Malloc(sizeof(PyFutureFeatures));
|
||||
if (ff == NULL) {
|
||||
PyErr_NoMemory();
|
||||
return NULL;
|
||||
}
|
||||
ff->ff_features = 0;
|
||||
ff->ff_lineno = -1;
|
||||
ff = (PyFutureFeatures *)PyObject_Malloc(sizeof(PyFutureFeatures));
|
||||
if (ff == NULL) {
|
||||
PyErr_NoMemory();
|
||||
return NULL;
|
||||
}
|
||||
ff->ff_features = 0;
|
||||
ff->ff_lineno = -1;
|
||||
|
||||
if (!future_parse(ff, mod, filename)) {
|
||||
PyObject_Free(ff);
|
||||
return NULL;
|
||||
}
|
||||
return ff;
|
||||
if (!future_parse(ff, mod, filename)) {
|
||||
PyObject_Free(ff);
|
||||
return NULL;
|
||||
}
|
||||
return ff;
|
||||
}
|
||||
|
|
3024
Python/getargs.c
3024
Python/getargs.c
File diff suppressed because it is too large
Load diff
|
@ -26,24 +26,24 @@ extern char *getwd(char *);
|
|||
char *
|
||||
getcwd(char *buf, int size)
|
||||
{
|
||||
char localbuf[MAXPATHLEN+1];
|
||||
char *ret;
|
||||
char localbuf[MAXPATHLEN+1];
|
||||
char *ret;
|
||||
|
||||
if (size <= 0) {
|
||||
errno = EINVAL;
|
||||
return NULL;
|
||||
}
|
||||
ret = getwd(localbuf);
|
||||
if (ret != NULL && strlen(localbuf) >= (size_t)size) {
|
||||
errno = ERANGE;
|
||||
return NULL;
|
||||
}
|
||||
if (ret == NULL) {
|
||||
errno = EACCES; /* Most likely error */
|
||||
return NULL;
|
||||
}
|
||||
strncpy(buf, localbuf, size);
|
||||
return buf;
|
||||
if (size <= 0) {
|
||||
errno = EINVAL;
|
||||
return NULL;
|
||||
}
|
||||
ret = getwd(localbuf);
|
||||
if (ret != NULL && strlen(localbuf) >= (size_t)size) {
|
||||
errno = ERANGE;
|
||||
return NULL;
|
||||
}
|
||||
if (ret == NULL) {
|
||||
errno = EACCES; /* Most likely error */
|
||||
return NULL;
|
||||
}
|
||||
strncpy(buf, localbuf, size);
|
||||
return buf;
|
||||
}
|
||||
|
||||
#else /* !HAVE_GETWD */
|
||||
|
@ -57,26 +57,26 @@ getcwd(char *buf, int size)
|
|||
char *
|
||||
getcwd(char *buf, int size)
|
||||
{
|
||||
FILE *fp;
|
||||
char *p;
|
||||
if (size <= 0) {
|
||||
errno = EINVAL;
|
||||
return NULL;
|
||||
}
|
||||
if ((fp = popen(PWD_CMD, "r")) == NULL)
|
||||
return NULL;
|
||||
if (fgets(buf, size, fp) == NULL || pclose(fp) != 0) {
|
||||
errno = EACCES; /* Most likely error */
|
||||
return NULL;
|
||||
}
|
||||
for (p = buf; *p != '\n'; p++) {
|
||||
if (*p == '\0') {
|
||||
errno = ERANGE;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
*p = '\0';
|
||||
return buf;
|
||||
FILE *fp;
|
||||
char *p;
|
||||
if (size <= 0) {
|
||||
errno = EINVAL;
|
||||
return NULL;
|
||||
}
|
||||
if ((fp = popen(PWD_CMD, "r")) == NULL)
|
||||
return NULL;
|
||||
if (fgets(buf, size, fp) == NULL || pclose(fp) != 0) {
|
||||
errno = EACCES; /* Most likely error */
|
||||
return NULL;
|
||||
}
|
||||
for (p = buf; *p != '\n'; p++) {
|
||||
if (*p == '\0') {
|
||||
errno = ERANGE;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
*p = '\0';
|
||||
return buf;
|
||||
}
|
||||
|
||||
#endif /* !HAVE_GETWD */
|
||||
|
|
122
Python/getopt.c
122
Python/getopt.c
|
@ -7,8 +7,8 @@
|
|||
*
|
||||
* All Rights Reserved
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software and its
|
||||
* documentation for any purpose and without fee is hereby granted,
|
||||
* Permission to use, copy, modify, and distribute this software and its
|
||||
* documentation for any purpose and without fee is hereby granted,
|
||||
* provided that the above copyright notice, this permission notice and
|
||||
* the following disclaimer notice appear unmodified in all copies.
|
||||
*
|
||||
|
@ -40,84 +40,84 @@ char *_PyOS_optarg = NULL; /* optional argument */
|
|||
|
||||
int _PyOS_GetOpt(int argc, char **argv, char *optstring)
|
||||
{
|
||||
static char *opt_ptr = "";
|
||||
char *ptr;
|
||||
int option;
|
||||
static char *opt_ptr = "";
|
||||
char *ptr;
|
||||
int option;
|
||||
|
||||
if (*opt_ptr == '\0') {
|
||||
if (*opt_ptr == '\0') {
|
||||
|
||||
if (_PyOS_optind >= argc)
|
||||
return -1;
|
||||
if (_PyOS_optind >= argc)
|
||||
return -1;
|
||||
#ifdef MS_WINDOWS
|
||||
else if (strcmp(argv[_PyOS_optind], "/?") == 0) {
|
||||
++_PyOS_optind;
|
||||
return 'h';
|
||||
}
|
||||
else if (strcmp(argv[_PyOS_optind], "/?") == 0) {
|
||||
++_PyOS_optind;
|
||||
return 'h';
|
||||
}
|
||||
#endif
|
||||
|
||||
else if (argv[_PyOS_optind][0] != '-' ||
|
||||
argv[_PyOS_optind][1] == '\0' /* lone dash */ )
|
||||
return -1;
|
||||
else if (argv[_PyOS_optind][0] != '-' ||
|
||||
argv[_PyOS_optind][1] == '\0' /* lone dash */ )
|
||||
return -1;
|
||||
|
||||
else if (strcmp(argv[_PyOS_optind], "--") == 0) {
|
||||
++_PyOS_optind;
|
||||
return -1;
|
||||
}
|
||||
else if (strcmp(argv[_PyOS_optind], "--") == 0) {
|
||||
++_PyOS_optind;
|
||||
return -1;
|
||||
}
|
||||
|
||||
else if (strcmp(argv[_PyOS_optind], "--help") == 0) {
|
||||
++_PyOS_optind;
|
||||
return 'h';
|
||||
}
|
||||
else if (strcmp(argv[_PyOS_optind], "--help") == 0) {
|
||||
++_PyOS_optind;
|
||||
return 'h';
|
||||
}
|
||||
|
||||
else if (strcmp(argv[_PyOS_optind], "--version") == 0) {
|
||||
++_PyOS_optind;
|
||||
return 'V';
|
||||
}
|
||||
else if (strcmp(argv[_PyOS_optind], "--version") == 0) {
|
||||
++_PyOS_optind;
|
||||
return 'V';
|
||||
}
|
||||
|
||||
|
||||
opt_ptr = &argv[_PyOS_optind++][1];
|
||||
}
|
||||
opt_ptr = &argv[_PyOS_optind++][1];
|
||||
}
|
||||
|
||||
if ( (option = *opt_ptr++) == '\0')
|
||||
return -1;
|
||||
if ( (option = *opt_ptr++) == '\0')
|
||||
return -1;
|
||||
|
||||
if (option == 'J') {
|
||||
fprintf(stderr, "-J is reserved for Jython\n");
|
||||
return '_';
|
||||
}
|
||||
if (option == 'J') {
|
||||
fprintf(stderr, "-J is reserved for Jython\n");
|
||||
return '_';
|
||||
}
|
||||
|
||||
if (option == 'X') {
|
||||
fprintf(stderr,
|
||||
"-X is reserved for implementation-specific arguments\n");
|
||||
return '_';
|
||||
}
|
||||
if (option == 'X') {
|
||||
fprintf(stderr,
|
||||
"-X is reserved for implementation-specific arguments\n");
|
||||
return '_';
|
||||
}
|
||||
|
||||
if ((ptr = strchr(optstring, option)) == NULL) {
|
||||
if (_PyOS_opterr)
|
||||
fprintf(stderr, "Unknown option: -%c\n", option);
|
||||
if ((ptr = strchr(optstring, option)) == NULL) {
|
||||
if (_PyOS_opterr)
|
||||
fprintf(stderr, "Unknown option: -%c\n", option);
|
||||
|
||||
return '_';
|
||||
}
|
||||
return '_';
|
||||
}
|
||||
|
||||
if (*(ptr + 1) == ':') {
|
||||
if (*opt_ptr != '\0') {
|
||||
_PyOS_optarg = opt_ptr;
|
||||
opt_ptr = "";
|
||||
}
|
||||
if (*(ptr + 1) == ':') {
|
||||
if (*opt_ptr != '\0') {
|
||||
_PyOS_optarg = opt_ptr;
|
||||
opt_ptr = "";
|
||||
}
|
||||
|
||||
else {
|
||||
if (_PyOS_optind >= argc) {
|
||||
if (_PyOS_opterr)
|
||||
fprintf(stderr,
|
||||
"Argument expected for the -%c option\n", option);
|
||||
return '_';
|
||||
}
|
||||
else {
|
||||
if (_PyOS_optind >= argc) {
|
||||
if (_PyOS_opterr)
|
||||
fprintf(stderr,
|
||||
"Argument expected for the -%c option\n", option);
|
||||
return '_';
|
||||
}
|
||||
|
||||
_PyOS_optarg = argv[_PyOS_optind++];
|
||||
}
|
||||
}
|
||||
_PyOS_optarg = argv[_PyOS_optind++];
|
||||
}
|
||||
}
|
||||
|
||||
return option;
|
||||
return option;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
4564
Python/import.c
4564
Python/import.c
File diff suppressed because it is too large
Load diff
|
@ -13,66 +13,66 @@
|
|||
#include "importdl.h"
|
||||
|
||||
extern dl_funcptr _PyImport_GetDynLoadFunc(const char *name,
|
||||
const char *shortname,
|
||||
const char *pathname, FILE *fp);
|
||||
const char *shortname,
|
||||
const char *pathname, FILE *fp);
|
||||
|
||||
|
||||
|
||||
PyObject *
|
||||
_PyImport_LoadDynamicModule(char *name, char *pathname, FILE *fp)
|
||||
{
|
||||
PyObject *m;
|
||||
char *lastdot, *shortname, *packagecontext, *oldcontext;
|
||||
dl_funcptr p;
|
||||
PyObject *m;
|
||||
char *lastdot, *shortname, *packagecontext, *oldcontext;
|
||||
dl_funcptr p;
|
||||
|
||||
if ((m = _PyImport_FindExtension(name, pathname)) != NULL) {
|
||||
Py_INCREF(m);
|
||||
return m;
|
||||
}
|
||||
lastdot = strrchr(name, '.');
|
||||
if (lastdot == NULL) {
|
||||
packagecontext = NULL;
|
||||
shortname = name;
|
||||
}
|
||||
else {
|
||||
packagecontext = name;
|
||||
shortname = lastdot+1;
|
||||
}
|
||||
if ((m = _PyImport_FindExtension(name, pathname)) != NULL) {
|
||||
Py_INCREF(m);
|
||||
return m;
|
||||
}
|
||||
lastdot = strrchr(name, '.');
|
||||
if (lastdot == NULL) {
|
||||
packagecontext = NULL;
|
||||
shortname = name;
|
||||
}
|
||||
else {
|
||||
packagecontext = name;
|
||||
shortname = lastdot+1;
|
||||
}
|
||||
|
||||
p = _PyImport_GetDynLoadFunc(name, shortname, pathname, fp);
|
||||
if (PyErr_Occurred())
|
||||
return NULL;
|
||||
if (p == NULL) {
|
||||
PyErr_Format(PyExc_ImportError,
|
||||
"dynamic module does not define init function (init%.200s)",
|
||||
shortname);
|
||||
return NULL;
|
||||
}
|
||||
oldcontext = _Py_PackageContext;
|
||||
_Py_PackageContext = packagecontext;
|
||||
(*p)();
|
||||
_Py_PackageContext = oldcontext;
|
||||
if (PyErr_Occurred())
|
||||
return NULL;
|
||||
p = _PyImport_GetDynLoadFunc(name, shortname, pathname, fp);
|
||||
if (PyErr_Occurred())
|
||||
return NULL;
|
||||
if (p == NULL) {
|
||||
PyErr_Format(PyExc_ImportError,
|
||||
"dynamic module does not define init function (init%.200s)",
|
||||
shortname);
|
||||
return NULL;
|
||||
}
|
||||
oldcontext = _Py_PackageContext;
|
||||
_Py_PackageContext = packagecontext;
|
||||
(*p)();
|
||||
_Py_PackageContext = oldcontext;
|
||||
if (PyErr_Occurred())
|
||||
return NULL;
|
||||
|
||||
m = PyDict_GetItemString(PyImport_GetModuleDict(), name);
|
||||
if (m == NULL) {
|
||||
PyErr_SetString(PyExc_SystemError,
|
||||
"dynamic module not initialized properly");
|
||||
return NULL;
|
||||
}
|
||||
/* Remember the filename as the __file__ attribute */
|
||||
if (PyModule_AddStringConstant(m, "__file__", pathname) < 0)
|
||||
PyErr_Clear(); /* Not important enough to report */
|
||||
m = PyDict_GetItemString(PyImport_GetModuleDict(), name);
|
||||
if (m == NULL) {
|
||||
PyErr_SetString(PyExc_SystemError,
|
||||
"dynamic module not initialized properly");
|
||||
return NULL;
|
||||
}
|
||||
/* Remember the filename as the __file__ attribute */
|
||||
if (PyModule_AddStringConstant(m, "__file__", pathname) < 0)
|
||||
PyErr_Clear(); /* Not important enough to report */
|
||||
|
||||
if (_PyImport_FixupExtension(name, pathname) == NULL)
|
||||
return NULL;
|
||||
if (Py_VerboseFlag)
|
||||
PySys_WriteStderr(
|
||||
"import %s # dynamically loaded from %s\n",
|
||||
name, pathname);
|
||||
Py_INCREF(m);
|
||||
return m;
|
||||
if (_PyImport_FixupExtension(name, pathname) == NULL)
|
||||
return NULL;
|
||||
if (Py_VerboseFlag)
|
||||
PySys_WriteStderr(
|
||||
"import %s # dynamically loaded from %s\n",
|
||||
name, pathname);
|
||||
Py_INCREF(m);
|
||||
return m;
|
||||
}
|
||||
|
||||
#endif /* HAVE_DYNAMIC_LOADING */
|
||||
|
|
|
@ -8,28 +8,28 @@ extern "C" {
|
|||
|
||||
/* Definitions for dynamic loading of extension modules */
|
||||
enum filetype {
|
||||
SEARCH_ERROR,
|
||||
PY_SOURCE,
|
||||
PY_COMPILED,
|
||||
C_EXTENSION,
|
||||
PY_RESOURCE, /* Mac only */
|
||||
PKG_DIRECTORY,
|
||||
C_BUILTIN,
|
||||
PY_FROZEN,
|
||||
PY_CODERESOURCE, /* Mac only */
|
||||
IMP_HOOK
|
||||
SEARCH_ERROR,
|
||||
PY_SOURCE,
|
||||
PY_COMPILED,
|
||||
C_EXTENSION,
|
||||
PY_RESOURCE, /* Mac only */
|
||||
PKG_DIRECTORY,
|
||||
C_BUILTIN,
|
||||
PY_FROZEN,
|
||||
PY_CODERESOURCE, /* Mac only */
|
||||
IMP_HOOK
|
||||
};
|
||||
|
||||
struct filedescr {
|
||||
char *suffix;
|
||||
char *mode;
|
||||
enum filetype type;
|
||||
char *suffix;
|
||||
char *mode;
|
||||
enum filetype type;
|
||||
};
|
||||
extern struct filedescr * _PyImport_Filetab;
|
||||
extern const struct filedescr _PyImport_DynLoadFiletab[];
|
||||
|
||||
extern PyObject *_PyImport_LoadDynamicModule(char *name, char *pathname,
|
||||
FILE *);
|
||||
FILE *);
|
||||
|
||||
/* Max length of module suffix searched for -- accommodates "module.slb" */
|
||||
#define MAXSUFFIXSIZE 12
|
||||
|
|
|
@ -4,10 +4,10 @@ The Netherlands.
|
|||
|
||||
All Rights Reserved
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose and without fee is hereby granted,
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose and without fee is hereby granted,
|
||||
provided that the above copyright notice appear in all copies and that
|
||||
both that copyright notice and this permission notice appear in
|
||||
both that copyright notice and this permission notice appear in
|
||||
supporting documentation, and that the names of Stichting Mathematisch
|
||||
Centrum or CWI not be used in advertising or publicity pertaining to
|
||||
distribution of the software without specific, written prior permission.
|
||||
|
@ -25,45 +25,45 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|||
|
||||
#include "Python.h"
|
||||
#include "pymactoolbox.h"
|
||||
#include <arpa/inet.h> /* for ntohl, htonl */
|
||||
#include <arpa/inet.h> /* for ntohl, htonl */
|
||||
|
||||
|
||||
/* Like strerror() but for Mac OS error numbers */
|
||||
char *
|
||||
PyMac_StrError(int err)
|
||||
{
|
||||
static char buf[256];
|
||||
PyObject *m;
|
||||
PyObject *rv;
|
||||
static char buf[256];
|
||||
PyObject *m;
|
||||
PyObject *rv;
|
||||
|
||||
m = PyImport_ImportModuleNoBlock("MacOS");
|
||||
if (!m) {
|
||||
if (Py_VerboseFlag)
|
||||
PyErr_Print();
|
||||
PyErr_Clear();
|
||||
rv = NULL;
|
||||
}
|
||||
else {
|
||||
rv = PyObject_CallMethod(m, "GetErrorString", "i", err);
|
||||
if (!rv)
|
||||
PyErr_Clear();
|
||||
}
|
||||
if (!rv) {
|
||||
buf[0] = '\0';
|
||||
}
|
||||
else {
|
||||
char *input = PyString_AsString(rv);
|
||||
if (!input) {
|
||||
PyErr_Clear();
|
||||
buf[0] = '\0';
|
||||
} else {
|
||||
strncpy(buf, input, sizeof(buf) - 1);
|
||||
buf[sizeof(buf) - 1] = '\0';
|
||||
}
|
||||
Py_DECREF(rv);
|
||||
}
|
||||
Py_XDECREF(m);
|
||||
return buf;
|
||||
m = PyImport_ImportModuleNoBlock("MacOS");
|
||||
if (!m) {
|
||||
if (Py_VerboseFlag)
|
||||
PyErr_Print();
|
||||
PyErr_Clear();
|
||||
rv = NULL;
|
||||
}
|
||||
else {
|
||||
rv = PyObject_CallMethod(m, "GetErrorString", "i", err);
|
||||
if (!rv)
|
||||
PyErr_Clear();
|
||||
}
|
||||
if (!rv) {
|
||||
buf[0] = '\0';
|
||||
}
|
||||
else {
|
||||
char *input = PyString_AsString(rv);
|
||||
if (!input) {
|
||||
PyErr_Clear();
|
||||
buf[0] = '\0';
|
||||
} else {
|
||||
strncpy(buf, input, sizeof(buf) - 1);
|
||||
buf[sizeof(buf) - 1] = '\0';
|
||||
}
|
||||
Py_DECREF(rv);
|
||||
}
|
||||
Py_XDECREF(m);
|
||||
return buf;
|
||||
}
|
||||
|
||||
/* Exception object shared by all Mac specific modules for Mac OS errors */
|
||||
|
@ -73,36 +73,36 @@ PyObject *PyMac_OSErrException;
|
|||
PyObject *
|
||||
PyMac_GetOSErrException(void)
|
||||
{
|
||||
if (PyMac_OSErrException == NULL)
|
||||
PyMac_OSErrException = PyErr_NewException("MacOS.Error", NULL, NULL);
|
||||
return PyMac_OSErrException;
|
||||
if (PyMac_OSErrException == NULL)
|
||||
PyMac_OSErrException = PyErr_NewException("MacOS.Error", NULL, NULL);
|
||||
return PyMac_OSErrException;
|
||||
}
|
||||
|
||||
/* Set a MAC-specific error from errno, and return NULL; return None if no error */
|
||||
PyObject *
|
||||
PyObject *
|
||||
PyErr_Mac(PyObject *eobj, int err)
|
||||
{
|
||||
char *msg;
|
||||
PyObject *v;
|
||||
|
||||
if (err == 0 && !PyErr_Occurred()) {
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
if (err == -1 && PyErr_Occurred())
|
||||
return NULL;
|
||||
msg = PyMac_StrError(err);
|
||||
v = Py_BuildValue("(is)", err, msg);
|
||||
PyErr_SetObject(eobj, v);
|
||||
Py_DECREF(v);
|
||||
return NULL;
|
||||
char *msg;
|
||||
PyObject *v;
|
||||
|
||||
if (err == 0 && !PyErr_Occurred()) {
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
if (err == -1 && PyErr_Occurred())
|
||||
return NULL;
|
||||
msg = PyMac_StrError(err);
|
||||
v = Py_BuildValue("(is)", err, msg);
|
||||
PyErr_SetObject(eobj, v);
|
||||
Py_DECREF(v);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Call PyErr_Mac with PyMac_OSErrException */
|
||||
PyObject *
|
||||
PyMac_Error(OSErr err)
|
||||
{
|
||||
return PyErr_Mac(PyMac_GetOSErrException(), err);
|
||||
return PyErr_Mac(PyMac_GetOSErrException(), err);
|
||||
}
|
||||
|
||||
|
||||
|
@ -110,49 +110,49 @@ PyMac_Error(OSErr err)
|
|||
OSErr
|
||||
PyMac_GetFullPathname(FSSpec *fss, char *path, int len)
|
||||
{
|
||||
PyObject *fs, *exc;
|
||||
PyObject *rv = NULL;
|
||||
char *input;
|
||||
OSErr err = noErr;
|
||||
PyObject *fs, *exc;
|
||||
PyObject *rv = NULL;
|
||||
char *input;
|
||||
OSErr err = noErr;
|
||||
|
||||
*path = '\0';
|
||||
*path = '\0';
|
||||
|
||||
fs = PyMac_BuildFSSpec(fss);
|
||||
if (!fs)
|
||||
goto error;
|
||||
fs = PyMac_BuildFSSpec(fss);
|
||||
if (!fs)
|
||||
goto error;
|
||||
|
||||
rv = PyObject_CallMethod(fs, "as_pathname", "");
|
||||
if (!rv)
|
||||
goto error;
|
||||
rv = PyObject_CallMethod(fs, "as_pathname", "");
|
||||
if (!rv)
|
||||
goto error;
|
||||
|
||||
input = PyString_AsString(rv);
|
||||
if (!input)
|
||||
goto error;
|
||||
input = PyString_AsString(rv);
|
||||
if (!input)
|
||||
goto error;
|
||||
|
||||
strncpy(path, input, len - 1);
|
||||
path[len - 1] = '\0';
|
||||
strncpy(path, input, len - 1);
|
||||
path[len - 1] = '\0';
|
||||
|
||||
Py_XDECREF(rv);
|
||||
Py_XDECREF(fs);
|
||||
return err;
|
||||
Py_XDECREF(rv);
|
||||
Py_XDECREF(fs);
|
||||
return err;
|
||||
|
||||
error:
|
||||
exc = PyErr_Occurred();
|
||||
if (exc && PyErr_GivenExceptionMatches(exc,
|
||||
PyMac_GetOSErrException())) {
|
||||
PyObject *args = PyObject_GetAttrString(exc, "args");
|
||||
if (args) {
|
||||
char *ignore;
|
||||
PyArg_ParseTuple(args, "is", &err, &ignore);
|
||||
Py_XDECREF(args);
|
||||
}
|
||||
}
|
||||
if (err == noErr)
|
||||
err = -1;
|
||||
PyErr_Clear();
|
||||
Py_XDECREF(rv);
|
||||
Py_XDECREF(fs);
|
||||
return err;
|
||||
exc = PyErr_Occurred();
|
||||
if (exc && PyErr_GivenExceptionMatches(exc,
|
||||
PyMac_GetOSErrException())) {
|
||||
PyObject *args = PyObject_GetAttrString(exc, "args");
|
||||
if (args) {
|
||||
char *ignore;
|
||||
PyArg_ParseTuple(args, "is", &err, &ignore);
|
||||
Py_XDECREF(args);
|
||||
}
|
||||
}
|
||||
if (err == noErr)
|
||||
err = -1;
|
||||
PyErr_Clear();
|
||||
Py_XDECREF(rv);
|
||||
Py_XDECREF(fs);
|
||||
return err;
|
||||
}
|
||||
#endif /* !__LP64__ */
|
||||
|
||||
|
@ -160,30 +160,30 @@ PyMac_GetFullPathname(FSSpec *fss, char *path, int len)
|
|||
int
|
||||
PyMac_GetOSType(PyObject *v, OSType *pr)
|
||||
{
|
||||
uint32_t tmp;
|
||||
if (!PyString_Check(v) || PyString_Size(v) != 4) {
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"OSType arg must be string of 4 chars");
|
||||
return 0;
|
||||
}
|
||||
memcpy((char *)&tmp, PyString_AsString(v), 4);
|
||||
*pr = (OSType)ntohl(tmp);
|
||||
return 1;
|
||||
uint32_t tmp;
|
||||
if (!PyString_Check(v) || PyString_Size(v) != 4) {
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"OSType arg must be string of 4 chars");
|
||||
return 0;
|
||||
}
|
||||
memcpy((char *)&tmp, PyString_AsString(v), 4);
|
||||
*pr = (OSType)ntohl(tmp);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Convert an OSType value to a 4-char string object */
|
||||
PyObject *
|
||||
PyMac_BuildOSType(OSType t)
|
||||
{
|
||||
uint32_t tmp = htonl((uint32_t)t);
|
||||
return PyString_FromStringAndSize((char *)&tmp, 4);
|
||||
uint32_t tmp = htonl((uint32_t)t);
|
||||
return PyString_FromStringAndSize((char *)&tmp, 4);
|
||||
}
|
||||
|
||||
/* Convert an NumVersion value to a 4-element tuple */
|
||||
PyObject *
|
||||
PyMac_BuildNumVersion(NumVersion t)
|
||||
{
|
||||
return Py_BuildValue("(hhhh)", t.majorRev, t.minorAndBugRev, t.stage, t.nonRelRev);
|
||||
return Py_BuildValue("(hhhh)", t.majorRev, t.minorAndBugRev, t.stage, t.nonRelRev);
|
||||
}
|
||||
|
||||
|
||||
|
@ -191,36 +191,36 @@ PyMac_BuildNumVersion(NumVersion t)
|
|||
int
|
||||
PyMac_GetStr255(PyObject *v, Str255 pbuf)
|
||||
{
|
||||
int len;
|
||||
if (!PyString_Check(v) || (len = PyString_Size(v)) > 255) {
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"Str255 arg must be string of at most 255 chars");
|
||||
return 0;
|
||||
}
|
||||
pbuf[0] = len;
|
||||
memcpy((char *)(pbuf+1), PyString_AsString(v), len);
|
||||
return 1;
|
||||
int len;
|
||||
if (!PyString_Check(v) || (len = PyString_Size(v)) > 255) {
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"Str255 arg must be string of at most 255 chars");
|
||||
return 0;
|
||||
}
|
||||
pbuf[0] = len;
|
||||
memcpy((char *)(pbuf+1), PyString_AsString(v), len);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Convert a Str255 to a Python string object */
|
||||
PyObject *
|
||||
PyMac_BuildStr255(Str255 s)
|
||||
{
|
||||
if ( s == NULL ) {
|
||||
PyErr_SetString(PyExc_SystemError, "Str255 pointer is NULL");
|
||||
return NULL;
|
||||
}
|
||||
return PyString_FromStringAndSize((char *)&s[1], (int)s[0]);
|
||||
if ( s == NULL ) {
|
||||
PyErr_SetString(PyExc_SystemError, "Str255 pointer is NULL");
|
||||
return NULL;
|
||||
}
|
||||
return PyString_FromStringAndSize((char *)&s[1], (int)s[0]);
|
||||
}
|
||||
|
||||
PyObject *
|
||||
PyMac_BuildOptStr255(Str255 s)
|
||||
{
|
||||
if ( s == NULL ) {
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
return PyString_FromStringAndSize((char *)&s[1], (int)s[0]);
|
||||
if ( s == NULL ) {
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
return PyString_FromStringAndSize((char *)&s[1], (int)s[0]);
|
||||
}
|
||||
|
||||
|
||||
|
@ -232,14 +232,14 @@ PyMac_BuildOptStr255(Str255 s)
|
|||
int
|
||||
PyMac_GetRect(PyObject *v, Rect *r)
|
||||
{
|
||||
return PyArg_Parse(v, "(hhhh)", &r->left, &r->top, &r->right, &r->bottom);
|
||||
return PyArg_Parse(v, "(hhhh)", &r->left, &r->top, &r->right, &r->bottom);
|
||||
}
|
||||
|
||||
/* Convert a Rect to a Python object */
|
||||
PyObject *
|
||||
PyMac_BuildRect(Rect *r)
|
||||
{
|
||||
return Py_BuildValue("(hhhh)", r->left, r->top, r->right, r->bottom);
|
||||
return Py_BuildValue("(hhhh)", r->left, r->top, r->right, r->bottom);
|
||||
}
|
||||
|
||||
|
||||
|
@ -250,14 +250,14 @@ PyMac_BuildRect(Rect *r)
|
|||
int
|
||||
PyMac_GetPoint(PyObject *v, Point *p)
|
||||
{
|
||||
return PyArg_Parse(v, "(hh)", &p->h, &p->v);
|
||||
return PyArg_Parse(v, "(hh)", &p->h, &p->v);
|
||||
}
|
||||
|
||||
/* Convert a Point to a Python object */
|
||||
PyObject *
|
||||
PyMac_BuildPoint(Point p)
|
||||
{
|
||||
return Py_BuildValue("(hh)", p.h, p.v);
|
||||
return Py_BuildValue("(hh)", p.h, p.v);
|
||||
}
|
||||
|
||||
|
||||
|
@ -266,73 +266,73 @@ PyMac_BuildPoint(Point p)
|
|||
int
|
||||
PyMac_GetEventRecord(PyObject *v, EventRecord *e)
|
||||
{
|
||||
return PyArg_Parse(v, "(Hkk(hh)H)",
|
||||
&e->what,
|
||||
&e->message,
|
||||
&e->when,
|
||||
&e->where.h,
|
||||
&e->where.v,
|
||||
&e->modifiers);
|
||||
return PyArg_Parse(v, "(Hkk(hh)H)",
|
||||
&e->what,
|
||||
&e->message,
|
||||
&e->when,
|
||||
&e->where.h,
|
||||
&e->where.v,
|
||||
&e->modifiers);
|
||||
}
|
||||
|
||||
/* Convert a Rect to an EventRecord object */
|
||||
PyObject *
|
||||
PyMac_BuildEventRecord(EventRecord *e)
|
||||
{
|
||||
return Py_BuildValue("(hll(hh)h)",
|
||||
e->what,
|
||||
e->message,
|
||||
e->when,
|
||||
e->where.h,
|
||||
e->where.v,
|
||||
e->modifiers);
|
||||
return Py_BuildValue("(hll(hh)h)",
|
||||
e->what,
|
||||
e->message,
|
||||
e->when,
|
||||
e->where.h,
|
||||
e->where.v,
|
||||
e->modifiers);
|
||||
}
|
||||
|
||||
/* Convert Python object to Fixed */
|
||||
int
|
||||
PyMac_GetFixed(PyObject *v, Fixed *f)
|
||||
{
|
||||
double d;
|
||||
|
||||
if( !PyArg_Parse(v, "d", &d))
|
||||
return 0;
|
||||
*f = (Fixed)(d * 0x10000);
|
||||
return 1;
|
||||
double d;
|
||||
|
||||
if( !PyArg_Parse(v, "d", &d))
|
||||
return 0;
|
||||
*f = (Fixed)(d * 0x10000);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Convert a Fixed to a Python object */
|
||||
PyObject *
|
||||
PyMac_BuildFixed(Fixed f)
|
||||
{
|
||||
double d;
|
||||
|
||||
d = f;
|
||||
d = d / 0x10000;
|
||||
return Py_BuildValue("d", d);
|
||||
double d;
|
||||
|
||||
d = f;
|
||||
d = d / 0x10000;
|
||||
return Py_BuildValue("d", d);
|
||||
}
|
||||
|
||||
/* Convert wide to/from Python int or (hi, lo) tuple. XXXX Should use Python longs */
|
||||
int
|
||||
PyMac_Getwide(PyObject *v, wide *rv)
|
||||
{
|
||||
if (PyInt_Check(v)) {
|
||||
rv->hi = 0;
|
||||
rv->lo = PyInt_AsLong(v);
|
||||
if( rv->lo & 0x80000000 )
|
||||
rv->hi = -1;
|
||||
return 1;
|
||||
}
|
||||
return PyArg_Parse(v, "(kk)", &rv->hi, &rv->lo);
|
||||
if (PyInt_Check(v)) {
|
||||
rv->hi = 0;
|
||||
rv->lo = PyInt_AsLong(v);
|
||||
if( rv->lo & 0x80000000 )
|
||||
rv->hi = -1;
|
||||
return 1;
|
||||
}
|
||||
return PyArg_Parse(v, "(kk)", &rv->hi, &rv->lo);
|
||||
}
|
||||
|
||||
|
||||
PyObject *
|
||||
PyMac_Buildwide(wide *w)
|
||||
{
|
||||
if ( (w->hi == 0 && (w->lo & 0x80000000) == 0) ||
|
||||
(w->hi == -1 && (w->lo & 0x80000000) ) )
|
||||
return PyInt_FromLong(w->lo);
|
||||
return Py_BuildValue("(ll)", w->hi, w->lo);
|
||||
if ( (w->hi == 0 && (w->lo & 0x80000000) == 0) ||
|
||||
(w->hi == -1 && (w->lo & 0x80000000) ) )
|
||||
return PyInt_FromLong(w->lo);
|
||||
return Py_BuildValue("(ll)", w->hi, w->lo);
|
||||
}
|
||||
|
||||
#ifdef USE_TOOLBOX_OBJECT_GLUE
|
||||
|
@ -358,8 +358,8 @@ PyObject *routinename(object cobj) { \
|
|||
if (!PyMacGluePtr_##routinename) { \
|
||||
if (!PyImport_ImportModule(module)) return NULL; \
|
||||
if (!PyMacGluePtr_##routinename) { \
|
||||
PyErr_SetString(PyExc_ImportError, "Module did not provide routine: " module ": " #routinename); \
|
||||
return NULL; \
|
||||
PyErr_SetString(PyExc_ImportError, "Module did not provide routine: " module ": " #routinename); \
|
||||
return NULL; \
|
||||
} \
|
||||
} \
|
||||
return (*PyMacGluePtr_##routinename)(cobj); \
|
||||
|
@ -372,8 +372,8 @@ int routinename(PyObject *pyobj, object *cobj) { \
|
|||
if (!PyMacGluePtr_##routinename) { \
|
||||
if (!PyImport_ImportModule(module)) return 0; \
|
||||
if (!PyMacGluePtr_##routinename) { \
|
||||
PyErr_SetString(PyExc_ImportError, "Module did not provide routine: " module ": " #routinename); \
|
||||
return 0; \
|
||||
PyErr_SetString(PyExc_ImportError, "Module did not provide routine: " module ": " #routinename); \
|
||||
return 0; \
|
||||
} \
|
||||
} \
|
||||
return (*PyMacGluePtr_##routinename)(pyobj, cobj); \
|
||||
|
|
2102
Python/marshal.c
2102
Python/marshal.c
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -20,20 +20,20 @@
|
|||
|
||||
Return value (rv):
|
||||
|
||||
When 0 <= rv < size, the output conversion was unexceptional, and
|
||||
rv characters were written to str (excluding a trailing \0 byte at
|
||||
str[rv]).
|
||||
When 0 <= rv < size, the output conversion was unexceptional, and
|
||||
rv characters were written to str (excluding a trailing \0 byte at
|
||||
str[rv]).
|
||||
|
||||
When rv >= size, output conversion was truncated, and a buffer of
|
||||
size rv+1 would have been needed to avoid truncation. str[size-1]
|
||||
is \0 in this case.
|
||||
When rv >= size, output conversion was truncated, and a buffer of
|
||||
size rv+1 would have been needed to avoid truncation. str[size-1]
|
||||
is \0 in this case.
|
||||
|
||||
When rv < 0, "something bad happened". str[size-1] is \0 in this
|
||||
case too, but the rest of str is unreliable. It could be that
|
||||
an error in format codes was detected by libc, or on platforms
|
||||
with a non-C99 vsnprintf simply that the buffer wasn't big enough
|
||||
to avoid truncation, or on platforms without any vsnprintf that
|
||||
PyMem_Malloc couldn't obtain space for a temp buffer.
|
||||
When rv < 0, "something bad happened". str[size-1] is \0 in this
|
||||
case too, but the rest of str is unreliable. It could be that
|
||||
an error in format codes was detected by libc, or on platforms
|
||||
with a non-C99 vsnprintf simply that the buffer wasn't big enough
|
||||
to avoid truncation, or on platforms without any vsnprintf that
|
||||
PyMem_Malloc couldn't obtain space for a temp buffer.
|
||||
|
||||
CAUTION: Unlike C99, str != NULL and size > 0 are required.
|
||||
*/
|
||||
|
@ -41,65 +41,65 @@
|
|||
int
|
||||
PyOS_snprintf(char *str, size_t size, const char *format, ...)
|
||||
{
|
||||
int rc;
|
||||
va_list va;
|
||||
int rc;
|
||||
va_list va;
|
||||
|
||||
va_start(va, format);
|
||||
rc = PyOS_vsnprintf(str, size, format, va);
|
||||
va_end(va);
|
||||
return rc;
|
||||
va_start(va, format);
|
||||
rc = PyOS_vsnprintf(str, size, format, va);
|
||||
va_end(va);
|
||||
return rc;
|
||||
}
|
||||
|
||||
int
|
||||
PyOS_vsnprintf(char *str, size_t size, const char *format, va_list va)
|
||||
{
|
||||
int len; /* # bytes written, excluding \0 */
|
||||
int len; /* # bytes written, excluding \0 */
|
||||
#ifdef HAVE_SNPRINTF
|
||||
#define _PyOS_vsnprintf_EXTRA_SPACE 1
|
||||
#else
|
||||
#define _PyOS_vsnprintf_EXTRA_SPACE 512
|
||||
char *buffer;
|
||||
char *buffer;
|
||||
#endif
|
||||
assert(str != NULL);
|
||||
assert(size > 0);
|
||||
assert(format != NULL);
|
||||
/* We take a size_t as input but return an int. Sanity check
|
||||
* our input so that it won't cause an overflow in the
|
||||
* vsnprintf return value or the buffer malloc size. */
|
||||
if (size > INT_MAX - _PyOS_vsnprintf_EXTRA_SPACE) {
|
||||
len = -666;
|
||||
goto Done;
|
||||
}
|
||||
assert(str != NULL);
|
||||
assert(size > 0);
|
||||
assert(format != NULL);
|
||||
/* We take a size_t as input but return an int. Sanity check
|
||||
* our input so that it won't cause an overflow in the
|
||||
* vsnprintf return value or the buffer malloc size. */
|
||||
if (size > INT_MAX - _PyOS_vsnprintf_EXTRA_SPACE) {
|
||||
len = -666;
|
||||
goto Done;
|
||||
}
|
||||
|
||||
#ifdef HAVE_SNPRINTF
|
||||
len = vsnprintf(str, size, format, va);
|
||||
len = vsnprintf(str, size, format, va);
|
||||
#else
|
||||
/* Emulate it. */
|
||||
buffer = PyMem_MALLOC(size + _PyOS_vsnprintf_EXTRA_SPACE);
|
||||
if (buffer == NULL) {
|
||||
len = -666;
|
||||
goto Done;
|
||||
}
|
||||
/* Emulate it. */
|
||||
buffer = PyMem_MALLOC(size + _PyOS_vsnprintf_EXTRA_SPACE);
|
||||
if (buffer == NULL) {
|
||||
len = -666;
|
||||
goto Done;
|
||||
}
|
||||
|
||||
len = vsprintf(buffer, format, va);
|
||||
if (len < 0)
|
||||
/* ignore the error */;
|
||||
len = vsprintf(buffer, format, va);
|
||||
if (len < 0)
|
||||
/* ignore the error */;
|
||||
|
||||
else if ((size_t)len >= size + _PyOS_vsnprintf_EXTRA_SPACE)
|
||||
Py_FatalError("Buffer overflow in PyOS_snprintf/PyOS_vsnprintf");
|
||||
else if ((size_t)len >= size + _PyOS_vsnprintf_EXTRA_SPACE)
|
||||
Py_FatalError("Buffer overflow in PyOS_snprintf/PyOS_vsnprintf");
|
||||
|
||||
else {
|
||||
const size_t to_copy = (size_t)len < size ?
|
||||
(size_t)len : size - 1;
|
||||
assert(to_copy < size);
|
||||
memcpy(str, buffer, to_copy);
|
||||
str[to_copy] = '\0';
|
||||
}
|
||||
PyMem_FREE(buffer);
|
||||
else {
|
||||
const size_t to_copy = (size_t)len < size ?
|
||||
(size_t)len : size - 1;
|
||||
assert(to_copy < size);
|
||||
memcpy(str, buffer, to_copy);
|
||||
str[to_copy] = '\0';
|
||||
}
|
||||
PyMem_FREE(buffer);
|
||||
#endif
|
||||
Done:
|
||||
if (size > 0)
|
||||
str[size-1] = '\0';
|
||||
return len;
|
||||
if (size > 0)
|
||||
str[size-1] = '\0';
|
||||
return len;
|
||||
#undef _PyOS_vsnprintf_EXTRA_SPACE
|
||||
}
|
||||
|
|
|
@ -18,43 +18,43 @@
|
|||
* i * base doesn't overflow unsigned long.
|
||||
*/
|
||||
static unsigned long smallmax[] = {
|
||||
0, /* bases 0 and 1 are invalid */
|
||||
0,
|
||||
ULONG_MAX / 2,
|
||||
ULONG_MAX / 3,
|
||||
ULONG_MAX / 4,
|
||||
ULONG_MAX / 5,
|
||||
ULONG_MAX / 6,
|
||||
ULONG_MAX / 7,
|
||||
ULONG_MAX / 8,
|
||||
ULONG_MAX / 9,
|
||||
ULONG_MAX / 10,
|
||||
ULONG_MAX / 11,
|
||||
ULONG_MAX / 12,
|
||||
ULONG_MAX / 13,
|
||||
ULONG_MAX / 14,
|
||||
ULONG_MAX / 15,
|
||||
ULONG_MAX / 16,
|
||||
ULONG_MAX / 17,
|
||||
ULONG_MAX / 18,
|
||||
ULONG_MAX / 19,
|
||||
ULONG_MAX / 20,
|
||||
ULONG_MAX / 21,
|
||||
ULONG_MAX / 22,
|
||||
ULONG_MAX / 23,
|
||||
ULONG_MAX / 24,
|
||||
ULONG_MAX / 25,
|
||||
ULONG_MAX / 26,
|
||||
ULONG_MAX / 27,
|
||||
ULONG_MAX / 28,
|
||||
ULONG_MAX / 29,
|
||||
ULONG_MAX / 30,
|
||||
ULONG_MAX / 31,
|
||||
ULONG_MAX / 32,
|
||||
ULONG_MAX / 33,
|
||||
ULONG_MAX / 34,
|
||||
ULONG_MAX / 35,
|
||||
ULONG_MAX / 36,
|
||||
0, /* bases 0 and 1 are invalid */
|
||||
0,
|
||||
ULONG_MAX / 2,
|
||||
ULONG_MAX / 3,
|
||||
ULONG_MAX / 4,
|
||||
ULONG_MAX / 5,
|
||||
ULONG_MAX / 6,
|
||||
ULONG_MAX / 7,
|
||||
ULONG_MAX / 8,
|
||||
ULONG_MAX / 9,
|
||||
ULONG_MAX / 10,
|
||||
ULONG_MAX / 11,
|
||||
ULONG_MAX / 12,
|
||||
ULONG_MAX / 13,
|
||||
ULONG_MAX / 14,
|
||||
ULONG_MAX / 15,
|
||||
ULONG_MAX / 16,
|
||||
ULONG_MAX / 17,
|
||||
ULONG_MAX / 18,
|
||||
ULONG_MAX / 19,
|
||||
ULONG_MAX / 20,
|
||||
ULONG_MAX / 21,
|
||||
ULONG_MAX / 22,
|
||||
ULONG_MAX / 23,
|
||||
ULONG_MAX / 24,
|
||||
ULONG_MAX / 25,
|
||||
ULONG_MAX / 26,
|
||||
ULONG_MAX / 27,
|
||||
ULONG_MAX / 28,
|
||||
ULONG_MAX / 29,
|
||||
ULONG_MAX / 30,
|
||||
ULONG_MAX / 31,
|
||||
ULONG_MAX / 32,
|
||||
ULONG_MAX / 33,
|
||||
ULONG_MAX / 34,
|
||||
ULONG_MAX / 35,
|
||||
ULONG_MAX / 36,
|
||||
};
|
||||
|
||||
/* maximum digits that can't ever overflow for bases 2 through 36,
|
||||
|
@ -63,223 +63,223 @@ static unsigned long smallmax[] = {
|
|||
*/
|
||||
#if SIZEOF_LONG == 4
|
||||
static int digitlimit[] = {
|
||||
0, 0, 32, 20, 16, 13, 12, 11, 10, 10, /* 0 - 9 */
|
||||
9, 9, 8, 8, 8, 8, 8, 7, 7, 7, /* 10 - 19 */
|
||||
7, 7, 7, 7, 6, 6, 6, 6, 6, 6, /* 20 - 29 */
|
||||
6, 6, 6, 6, 6, 6, 6}; /* 30 - 36 */
|
||||
0, 0, 32, 20, 16, 13, 12, 11, 10, 10, /* 0 - 9 */
|
||||
9, 9, 8, 8, 8, 8, 8, 7, 7, 7, /* 10 - 19 */
|
||||
7, 7, 7, 7, 6, 6, 6, 6, 6, 6, /* 20 - 29 */
|
||||
6, 6, 6, 6, 6, 6, 6}; /* 30 - 36 */
|
||||
#elif SIZEOF_LONG == 8
|
||||
/* [int(math.floor(math.log(2**64, i))) for i in range(2, 37)] */
|
||||
static int digitlimit[] = {
|
||||
0, 0, 64, 40, 32, 27, 24, 22, 21, 20, /* 0 - 9 */
|
||||
19, 18, 17, 17, 16, 16, 16, 15, 15, 15, /* 10 - 19 */
|
||||
14, 14, 14, 14, 13, 13, 13, 13, 13, 13, /* 20 - 29 */
|
||||
13, 12, 12, 12, 12, 12, 12}; /* 30 - 36 */
|
||||
0, 0, 64, 40, 32, 27, 24, 22, 21, 20, /* 0 - 9 */
|
||||
19, 18, 17, 17, 16, 16, 16, 15, 15, 15, /* 10 - 19 */
|
||||
14, 14, 14, 14, 13, 13, 13, 13, 13, 13, /* 20 - 29 */
|
||||
13, 12, 12, 12, 12, 12, 12}; /* 30 - 36 */
|
||||
#else
|
||||
#error "Need table for SIZEOF_LONG"
|
||||
#endif
|
||||
|
||||
/*
|
||||
** strtoul
|
||||
** This is a general purpose routine for converting
|
||||
** an ascii string to an integer in an arbitrary base.
|
||||
** Leading white space is ignored. If 'base' is zero
|
||||
** it looks for a leading 0, 0b, 0B, 0o, 0O, 0x or 0X
|
||||
** to tell which base. If these are absent it defaults
|
||||
** to 10. Base must be 0 or between 2 and 36 (inclusive).
|
||||
** If 'ptr' is non-NULL it will contain a pointer to
|
||||
** the end of the scan.
|
||||
** Errors due to bad pointers will probably result in
|
||||
** exceptions - we don't check for them.
|
||||
** strtoul
|
||||
** This is a general purpose routine for converting
|
||||
** an ascii string to an integer in an arbitrary base.
|
||||
** Leading white space is ignored. If 'base' is zero
|
||||
** it looks for a leading 0, 0b, 0B, 0o, 0O, 0x or 0X
|
||||
** to tell which base. If these are absent it defaults
|
||||
** to 10. Base must be 0 or between 2 and 36 (inclusive).
|
||||
** If 'ptr' is non-NULL it will contain a pointer to
|
||||
** the end of the scan.
|
||||
** Errors due to bad pointers will probably result in
|
||||
** exceptions - we don't check for them.
|
||||
*/
|
||||
unsigned long
|
||||
PyOS_strtoul(register char *str, char **ptr, int base)
|
||||
{
|
||||
register unsigned long result = 0; /* return value of the function */
|
||||
register int c; /* current input character */
|
||||
register int ovlimit; /* required digits to overflow */
|
||||
register unsigned long result = 0; /* return value of the function */
|
||||
register int c; /* current input character */
|
||||
register int ovlimit; /* required digits to overflow */
|
||||
|
||||
/* skip leading white space */
|
||||
while (*str && isspace(Py_CHARMASK(*str)))
|
||||
++str;
|
||||
/* skip leading white space */
|
||||
while (*str && isspace(Py_CHARMASK(*str)))
|
||||
++str;
|
||||
|
||||
/* check for leading 0 or 0x for auto-base or base 16 */
|
||||
switch (base) {
|
||||
case 0: /* look for leading 0, 0b, 0o or 0x */
|
||||
if (*str == '0') {
|
||||
++str;
|
||||
if (*str == 'x' || *str == 'X') {
|
||||
/* there must be at least one digit after 0x */
|
||||
if (_PyLong_DigitValue[Py_CHARMASK(str[1])] >= 16) {
|
||||
if (ptr)
|
||||
*ptr = str;
|
||||
return 0;
|
||||
}
|
||||
++str;
|
||||
base = 16;
|
||||
} else if (*str == 'o' || *str == 'O') {
|
||||
/* there must be at least one digit after 0o */
|
||||
if (_PyLong_DigitValue[Py_CHARMASK(str[1])] >= 8) {
|
||||
if (ptr)
|
||||
*ptr = str;
|
||||
return 0;
|
||||
}
|
||||
++str;
|
||||
base = 8;
|
||||
} else if (*str == 'b' || *str == 'B') {
|
||||
/* there must be at least one digit after 0b */
|
||||
if (_PyLong_DigitValue[Py_CHARMASK(str[1])] >= 2) {
|
||||
if (ptr)
|
||||
*ptr = str;
|
||||
return 0;
|
||||
}
|
||||
++str;
|
||||
base = 2;
|
||||
} else {
|
||||
base = 8;
|
||||
}
|
||||
}
|
||||
else
|
||||
base = 10;
|
||||
break;
|
||||
/* check for leading 0 or 0x for auto-base or base 16 */
|
||||
switch (base) {
|
||||
case 0: /* look for leading 0, 0b, 0o or 0x */
|
||||
if (*str == '0') {
|
||||
++str;
|
||||
if (*str == 'x' || *str == 'X') {
|
||||
/* there must be at least one digit after 0x */
|
||||
if (_PyLong_DigitValue[Py_CHARMASK(str[1])] >= 16) {
|
||||
if (ptr)
|
||||
*ptr = str;
|
||||
return 0;
|
||||
}
|
||||
++str;
|
||||
base = 16;
|
||||
} else if (*str == 'o' || *str == 'O') {
|
||||
/* there must be at least one digit after 0o */
|
||||
if (_PyLong_DigitValue[Py_CHARMASK(str[1])] >= 8) {
|
||||
if (ptr)
|
||||
*ptr = str;
|
||||
return 0;
|
||||
}
|
||||
++str;
|
||||
base = 8;
|
||||
} else if (*str == 'b' || *str == 'B') {
|
||||
/* there must be at least one digit after 0b */
|
||||
if (_PyLong_DigitValue[Py_CHARMASK(str[1])] >= 2) {
|
||||
if (ptr)
|
||||
*ptr = str;
|
||||
return 0;
|
||||
}
|
||||
++str;
|
||||
base = 2;
|
||||
} else {
|
||||
base = 8;
|
||||
}
|
||||
}
|
||||
else
|
||||
base = 10;
|
||||
break;
|
||||
|
||||
case 2: /* skip leading 0b or 0B */
|
||||
if (*str == '0') {
|
||||
++str;
|
||||
if (*str == 'b' || *str == 'B') {
|
||||
/* there must be at least one digit after 0b */
|
||||
if (_PyLong_DigitValue[Py_CHARMASK(str[1])] >= 2) {
|
||||
if (ptr)
|
||||
*ptr = str;
|
||||
return 0;
|
||||
}
|
||||
++str;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 2: /* skip leading 0b or 0B */
|
||||
if (*str == '0') {
|
||||
++str;
|
||||
if (*str == 'b' || *str == 'B') {
|
||||
/* there must be at least one digit after 0b */
|
||||
if (_PyLong_DigitValue[Py_CHARMASK(str[1])] >= 2) {
|
||||
if (ptr)
|
||||
*ptr = str;
|
||||
return 0;
|
||||
}
|
||||
++str;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 8: /* skip leading 0o or 0O */
|
||||
if (*str == '0') {
|
||||
++str;
|
||||
if (*str == 'o' || *str == 'O') {
|
||||
/* there must be at least one digit after 0o */
|
||||
if (_PyLong_DigitValue[Py_CHARMASK(str[1])] >= 8) {
|
||||
if (ptr)
|
||||
*ptr = str;
|
||||
return 0;
|
||||
}
|
||||
++str;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 8: /* skip leading 0o or 0O */
|
||||
if (*str == '0') {
|
||||
++str;
|
||||
if (*str == 'o' || *str == 'O') {
|
||||
/* there must be at least one digit after 0o */
|
||||
if (_PyLong_DigitValue[Py_CHARMASK(str[1])] >= 8) {
|
||||
if (ptr)
|
||||
*ptr = str;
|
||||
return 0;
|
||||
}
|
||||
++str;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 16: /* skip leading 0x or 0X */
|
||||
if (*str == '0') {
|
||||
++str;
|
||||
if (*str == 'x' || *str == 'X') {
|
||||
/* there must be at least one digit after 0x */
|
||||
if (_PyLong_DigitValue[Py_CHARMASK(str[1])] >= 16) {
|
||||
if (ptr)
|
||||
*ptr = str;
|
||||
return 0;
|
||||
}
|
||||
++str;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 16: /* skip leading 0x or 0X */
|
||||
if (*str == '0') {
|
||||
++str;
|
||||
if (*str == 'x' || *str == 'X') {
|
||||
/* there must be at least one digit after 0x */
|
||||
if (_PyLong_DigitValue[Py_CHARMASK(str[1])] >= 16) {
|
||||
if (ptr)
|
||||
*ptr = str;
|
||||
return 0;
|
||||
}
|
||||
++str;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* catch silly bases */
|
||||
if (base < 2 || base > 36) {
|
||||
if (ptr)
|
||||
*ptr = str;
|
||||
return 0;
|
||||
}
|
||||
/* catch silly bases */
|
||||
if (base < 2 || base > 36) {
|
||||
if (ptr)
|
||||
*ptr = str;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* skip leading zeroes */
|
||||
while (*str == '0')
|
||||
++str;
|
||||
/* skip leading zeroes */
|
||||
while (*str == '0')
|
||||
++str;
|
||||
|
||||
/* base is guaranteed to be in [2, 36] at this point */
|
||||
ovlimit = digitlimit[base];
|
||||
/* base is guaranteed to be in [2, 36] at this point */
|
||||
ovlimit = digitlimit[base];
|
||||
|
||||
/* do the conversion until non-digit character encountered */
|
||||
while ((c = _PyLong_DigitValue[Py_CHARMASK(*str)]) < base) {
|
||||
if (ovlimit > 0) /* no overflow check required */
|
||||
result = result * base + c;
|
||||
else { /* requires overflow check */
|
||||
register unsigned long temp_result;
|
||||
/* do the conversion until non-digit character encountered */
|
||||
while ((c = _PyLong_DigitValue[Py_CHARMASK(*str)]) < base) {
|
||||
if (ovlimit > 0) /* no overflow check required */
|
||||
result = result * base + c;
|
||||
else { /* requires overflow check */
|
||||
register unsigned long temp_result;
|
||||
|
||||
if (ovlimit < 0) /* guaranteed overflow */
|
||||
goto overflowed;
|
||||
if (ovlimit < 0) /* guaranteed overflow */
|
||||
goto overflowed;
|
||||
|
||||
/* there could be an overflow */
|
||||
/* check overflow just from shifting */
|
||||
if (result > smallmax[base])
|
||||
goto overflowed;
|
||||
/* there could be an overflow */
|
||||
/* check overflow just from shifting */
|
||||
if (result > smallmax[base])
|
||||
goto overflowed;
|
||||
|
||||
result *= base;
|
||||
result *= base;
|
||||
|
||||
/* check overflow from the digit's value */
|
||||
temp_result = result + c;
|
||||
if (temp_result < result)
|
||||
goto overflowed;
|
||||
/* check overflow from the digit's value */
|
||||
temp_result = result + c;
|
||||
if (temp_result < result)
|
||||
goto overflowed;
|
||||
|
||||
result = temp_result;
|
||||
}
|
||||
result = temp_result;
|
||||
}
|
||||
|
||||
++str;
|
||||
--ovlimit;
|
||||
}
|
||||
++str;
|
||||
--ovlimit;
|
||||
}
|
||||
|
||||
/* set pointer to point to the last character scanned */
|
||||
if (ptr)
|
||||
*ptr = str;
|
||||
/* set pointer to point to the last character scanned */
|
||||
if (ptr)
|
||||
*ptr = str;
|
||||
|
||||
return result;
|
||||
return result;
|
||||
|
||||
overflowed:
|
||||
if (ptr) {
|
||||
/* spool through remaining digit characters */
|
||||
while (_PyLong_DigitValue[Py_CHARMASK(*str)] < base)
|
||||
++str;
|
||||
*ptr = str;
|
||||
}
|
||||
errno = ERANGE;
|
||||
return (unsigned long)-1;
|
||||
if (ptr) {
|
||||
/* spool through remaining digit characters */
|
||||
while (_PyLong_DigitValue[Py_CHARMASK(*str)] < base)
|
||||
++str;
|
||||
*ptr = str;
|
||||
}
|
||||
errno = ERANGE;
|
||||
return (unsigned long)-1;
|
||||
}
|
||||
|
||||
/* Checking for overflow in PyOS_strtol is a PITA; see comments
|
||||
* about PY_ABS_LONG_MIN in longobject.c.
|
||||
*/
|
||||
#define PY_ABS_LONG_MIN (0-(unsigned long)LONG_MIN)
|
||||
#define PY_ABS_LONG_MIN (0-(unsigned long)LONG_MIN)
|
||||
|
||||
long
|
||||
PyOS_strtol(char *str, char **ptr, int base)
|
||||
{
|
||||
long result;
|
||||
unsigned long uresult;
|
||||
char sign;
|
||||
long result;
|
||||
unsigned long uresult;
|
||||
char sign;
|
||||
|
||||
while (*str && isspace(Py_CHARMASK(*str)))
|
||||
str++;
|
||||
while (*str && isspace(Py_CHARMASK(*str)))
|
||||
str++;
|
||||
|
||||
sign = *str;
|
||||
if (sign == '+' || sign == '-')
|
||||
str++;
|
||||
sign = *str;
|
||||
if (sign == '+' || sign == '-')
|
||||
str++;
|
||||
|
||||
uresult = PyOS_strtoul(str, ptr, base);
|
||||
uresult = PyOS_strtoul(str, ptr, base);
|
||||
|
||||
if (uresult <= (unsigned long)LONG_MAX) {
|
||||
result = (long)uresult;
|
||||
if (sign == '-')
|
||||
result = -result;
|
||||
}
|
||||
else if (sign == '-' && uresult == PY_ABS_LONG_MIN) {
|
||||
result = LONG_MIN;
|
||||
}
|
||||
else {
|
||||
errno = ERANGE;
|
||||
result = LONG_MAX;
|
||||
}
|
||||
return result;
|
||||
if (uresult <= (unsigned long)LONG_MAX) {
|
||||
result = (long)uresult;
|
||||
if (sign == '-')
|
||||
result = -result;
|
||||
}
|
||||
else if (sign == '-' && uresult == PY_ABS_LONG_MIN) {
|
||||
result = LONG_MIN;
|
||||
}
|
||||
else {
|
||||
errno = ERANGE;
|
||||
result = LONG_MAX;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
|
1104
Python/peephole.c
1104
Python/peephole.c
File diff suppressed because it is too large
Load diff
284
Python/pyarena.c
284
Python/pyarena.c
|
@ -12,32 +12,32 @@
|
|||
*/
|
||||
|
||||
#define DEFAULT_BLOCK_SIZE 8192
|
||||
#define ALIGNMENT 8
|
||||
#define ALIGNMENT_MASK (ALIGNMENT - 1)
|
||||
#define ROUNDUP(x) (((x) + ALIGNMENT_MASK) & ~ALIGNMENT_MASK)
|
||||
#define ALIGNMENT 8
|
||||
#define ALIGNMENT_MASK (ALIGNMENT - 1)
|
||||
#define ROUNDUP(x) (((x) + ALIGNMENT_MASK) & ~ALIGNMENT_MASK)
|
||||
|
||||
typedef struct _block {
|
||||
/* Total number of bytes owned by this block available to pass out.
|
||||
* Read-only after initialization. The first such byte starts at
|
||||
* ab_mem.
|
||||
*/
|
||||
size_t ab_size;
|
||||
/* Total number of bytes owned by this block available to pass out.
|
||||
* Read-only after initialization. The first such byte starts at
|
||||
* ab_mem.
|
||||
*/
|
||||
size_t ab_size;
|
||||
|
||||
/* Total number of bytes already passed out. The next byte available
|
||||
* to pass out starts at ab_mem + ab_offset.
|
||||
*/
|
||||
size_t ab_offset;
|
||||
/* Total number of bytes already passed out. The next byte available
|
||||
* to pass out starts at ab_mem + ab_offset.
|
||||
*/
|
||||
size_t ab_offset;
|
||||
|
||||
/* An arena maintains a singly-linked, NULL-terminated list of
|
||||
* all blocks owned by the arena. These are linked via the
|
||||
* ab_next member.
|
||||
*/
|
||||
struct _block *ab_next;
|
||||
/* An arena maintains a singly-linked, NULL-terminated list of
|
||||
* all blocks owned by the arena. These are linked via the
|
||||
* ab_next member.
|
||||
*/
|
||||
struct _block *ab_next;
|
||||
|
||||
/* Pointer to the first allocatable byte owned by this block. Read-
|
||||
* only after initialization.
|
||||
*/
|
||||
void *ab_mem;
|
||||
/* Pointer to the first allocatable byte owned by this block. Read-
|
||||
* only after initialization.
|
||||
*/
|
||||
void *ab_mem;
|
||||
} block;
|
||||
|
||||
/* The arena manages two kinds of memory, blocks of raw memory
|
||||
|
@ -46,175 +46,175 @@ typedef struct _block {
|
|||
*/
|
||||
|
||||
struct _arena {
|
||||
/* Pointer to the first block allocated for the arena, never NULL.
|
||||
It is used only to find the first block when the arena is
|
||||
being freed.
|
||||
*/
|
||||
block *a_head;
|
||||
/* Pointer to the first block allocated for the arena, never NULL.
|
||||
It is used only to find the first block when the arena is
|
||||
being freed.
|
||||
*/
|
||||
block *a_head;
|
||||
|
||||
/* Pointer to the block currently used for allocation. It's
|
||||
ab_next field should be NULL. If it is not-null after a
|
||||
call to block_alloc(), it means a new block has been allocated
|
||||
and a_cur should be reset to point it.
|
||||
*/
|
||||
block *a_cur;
|
||||
/* Pointer to the block currently used for allocation. It's
|
||||
ab_next field should be NULL. If it is not-null after a
|
||||
call to block_alloc(), it means a new block has been allocated
|
||||
and a_cur should be reset to point it.
|
||||
*/
|
||||
block *a_cur;
|
||||
|
||||
/* A Python list object containing references to all the PyObject
|
||||
pointers associated with this area. They will be DECREFed
|
||||
when the arena is freed.
|
||||
*/
|
||||
PyObject *a_objects;
|
||||
/* A Python list object containing references to all the PyObject
|
||||
pointers associated with this area. They will be DECREFed
|
||||
when the arena is freed.
|
||||
*/
|
||||
PyObject *a_objects;
|
||||
|
||||
#if defined(Py_DEBUG)
|
||||
/* Debug output */
|
||||
size_t total_allocs;
|
||||
size_t total_size;
|
||||
size_t total_blocks;
|
||||
size_t total_block_size;
|
||||
size_t total_big_blocks;
|
||||
/* Debug output */
|
||||
size_t total_allocs;
|
||||
size_t total_size;
|
||||
size_t total_blocks;
|
||||
size_t total_block_size;
|
||||
size_t total_big_blocks;
|
||||
#endif
|
||||
};
|
||||
|
||||
static block *
|
||||
block_new(size_t size)
|
||||
{
|
||||
/* Allocate header and block as one unit.
|
||||
ab_mem points just past header. */
|
||||
block *b = (block *)malloc(sizeof(block) + size);
|
||||
if (!b)
|
||||
return NULL;
|
||||
b->ab_size = size;
|
||||
b->ab_mem = (void *)(b + 1);
|
||||
b->ab_next = NULL;
|
||||
b->ab_offset = ROUNDUP((Py_uintptr_t)(b->ab_mem)) -
|
||||
(Py_uintptr_t)(b->ab_mem);
|
||||
return b;
|
||||
/* Allocate header and block as one unit.
|
||||
ab_mem points just past header. */
|
||||
block *b = (block *)malloc(sizeof(block) + size);
|
||||
if (!b)
|
||||
return NULL;
|
||||
b->ab_size = size;
|
||||
b->ab_mem = (void *)(b + 1);
|
||||
b->ab_next = NULL;
|
||||
b->ab_offset = ROUNDUP((Py_uintptr_t)(b->ab_mem)) -
|
||||
(Py_uintptr_t)(b->ab_mem);
|
||||
return b;
|
||||
}
|
||||
|
||||
static void
|
||||
block_free(block *b) {
|
||||
while (b) {
|
||||
block *next = b->ab_next;
|
||||
free(b);
|
||||
b = next;
|
||||
}
|
||||
while (b) {
|
||||
block *next = b->ab_next;
|
||||
free(b);
|
||||
b = next;
|
||||
}
|
||||
}
|
||||
|
||||
static void *
|
||||
block_alloc(block *b, size_t size)
|
||||
{
|
||||
void *p;
|
||||
assert(b);
|
||||
size = ROUNDUP(size);
|
||||
if (b->ab_offset + size > b->ab_size) {
|
||||
/* If we need to allocate more memory than will fit in
|
||||
the default block, allocate a one-off block that is
|
||||
exactly the right size. */
|
||||
/* TODO(jhylton): Think about space waste at end of block */
|
||||
block *newbl = block_new(
|
||||
size < DEFAULT_BLOCK_SIZE ?
|
||||
DEFAULT_BLOCK_SIZE : size);
|
||||
if (!newbl)
|
||||
return NULL;
|
||||
assert(!b->ab_next);
|
||||
b->ab_next = newbl;
|
||||
b = newbl;
|
||||
}
|
||||
void *p;
|
||||
assert(b);
|
||||
size = ROUNDUP(size);
|
||||
if (b->ab_offset + size > b->ab_size) {
|
||||
/* If we need to allocate more memory than will fit in
|
||||
the default block, allocate a one-off block that is
|
||||
exactly the right size. */
|
||||
/* TODO(jhylton): Think about space waste at end of block */
|
||||
block *newbl = block_new(
|
||||
size < DEFAULT_BLOCK_SIZE ?
|
||||
DEFAULT_BLOCK_SIZE : size);
|
||||
if (!newbl)
|
||||
return NULL;
|
||||
assert(!b->ab_next);
|
||||
b->ab_next = newbl;
|
||||
b = newbl;
|
||||
}
|
||||
|
||||
assert(b->ab_offset + size <= b->ab_size);
|
||||
p = (void *)(((char *)b->ab_mem) + b->ab_offset);
|
||||
b->ab_offset += size;
|
||||
return p;
|
||||
assert(b->ab_offset + size <= b->ab_size);
|
||||
p = (void *)(((char *)b->ab_mem) + b->ab_offset);
|
||||
b->ab_offset += size;
|
||||
return p;
|
||||
}
|
||||
|
||||
PyArena *
|
||||
PyArena_New()
|
||||
{
|
||||
PyArena* arena = (PyArena *)malloc(sizeof(PyArena));
|
||||
if (!arena)
|
||||
return (PyArena*)PyErr_NoMemory();
|
||||
PyArena* arena = (PyArena *)malloc(sizeof(PyArena));
|
||||
if (!arena)
|
||||
return (PyArena*)PyErr_NoMemory();
|
||||
|
||||
arena->a_head = block_new(DEFAULT_BLOCK_SIZE);
|
||||
arena->a_cur = arena->a_head;
|
||||
if (!arena->a_head) {
|
||||
free((void *)arena);
|
||||
return (PyArena*)PyErr_NoMemory();
|
||||
}
|
||||
arena->a_objects = PyList_New(0);
|
||||
if (!arena->a_objects) {
|
||||
block_free(arena->a_head);
|
||||
free((void *)arena);
|
||||
return (PyArena*)PyErr_NoMemory();
|
||||
}
|
||||
arena->a_head = block_new(DEFAULT_BLOCK_SIZE);
|
||||
arena->a_cur = arena->a_head;
|
||||
if (!arena->a_head) {
|
||||
free((void *)arena);
|
||||
return (PyArena*)PyErr_NoMemory();
|
||||
}
|
||||
arena->a_objects = PyList_New(0);
|
||||
if (!arena->a_objects) {
|
||||
block_free(arena->a_head);
|
||||
free((void *)arena);
|
||||
return (PyArena*)PyErr_NoMemory();
|
||||
}
|
||||
#if defined(Py_DEBUG)
|
||||
arena->total_allocs = 0;
|
||||
arena->total_size = 0;
|
||||
arena->total_blocks = 1;
|
||||
arena->total_block_size = DEFAULT_BLOCK_SIZE;
|
||||
arena->total_big_blocks = 0;
|
||||
arena->total_allocs = 0;
|
||||
arena->total_size = 0;
|
||||
arena->total_blocks = 1;
|
||||
arena->total_block_size = DEFAULT_BLOCK_SIZE;
|
||||
arena->total_big_blocks = 0;
|
||||
#endif
|
||||
return arena;
|
||||
return arena;
|
||||
}
|
||||
|
||||
void
|
||||
PyArena_Free(PyArena *arena)
|
||||
{
|
||||
int r;
|
||||
assert(arena);
|
||||
int r;
|
||||
assert(arena);
|
||||
#if defined(Py_DEBUG)
|
||||
/*
|
||||
fprintf(stderr,
|
||||
"alloc=%d size=%d blocks=%d block_size=%d big=%d objects=%d\n",
|
||||
arena->total_allocs, arena->total_size, arena->total_blocks,
|
||||
arena->total_block_size, arena->total_big_blocks,
|
||||
PyList_Size(arena->a_objects));
|
||||
*/
|
||||
/*
|
||||
fprintf(stderr,
|
||||
"alloc=%d size=%d blocks=%d block_size=%d big=%d objects=%d\n",
|
||||
arena->total_allocs, arena->total_size, arena->total_blocks,
|
||||
arena->total_block_size, arena->total_big_blocks,
|
||||
PyList_Size(arena->a_objects));
|
||||
*/
|
||||
#endif
|
||||
block_free(arena->a_head);
|
||||
/* This property normally holds, except when the code being compiled
|
||||
is sys.getobjects(0), in which case there will be two references.
|
||||
assert(arena->a_objects->ob_refcnt == 1);
|
||||
*/
|
||||
block_free(arena->a_head);
|
||||
/* This property normally holds, except when the code being compiled
|
||||
is sys.getobjects(0), in which case there will be two references.
|
||||
assert(arena->a_objects->ob_refcnt == 1);
|
||||
*/
|
||||
|
||||
/* Clear all the elements from the list. This is necessary
|
||||
to guarantee that they will be DECREFed. */
|
||||
r = PyList_SetSlice(arena->a_objects,
|
||||
0, PyList_GET_SIZE(arena->a_objects), NULL);
|
||||
assert(r == 0);
|
||||
assert(PyList_GET_SIZE(arena->a_objects) == 0);
|
||||
Py_DECREF(arena->a_objects);
|
||||
free(arena);
|
||||
/* Clear all the elements from the list. This is necessary
|
||||
to guarantee that they will be DECREFed. */
|
||||
r = PyList_SetSlice(arena->a_objects,
|
||||
0, PyList_GET_SIZE(arena->a_objects), NULL);
|
||||
assert(r == 0);
|
||||
assert(PyList_GET_SIZE(arena->a_objects) == 0);
|
||||
Py_DECREF(arena->a_objects);
|
||||
free(arena);
|
||||
}
|
||||
|
||||
void *
|
||||
PyArena_Malloc(PyArena *arena, size_t size)
|
||||
{
|
||||
void *p = block_alloc(arena->a_cur, size);
|
||||
if (!p)
|
||||
return PyErr_NoMemory();
|
||||
void *p = block_alloc(arena->a_cur, size);
|
||||
if (!p)
|
||||
return PyErr_NoMemory();
|
||||
#if defined(Py_DEBUG)
|
||||
arena->total_allocs++;
|
||||
arena->total_size += size;
|
||||
arena->total_allocs++;
|
||||
arena->total_size += size;
|
||||
#endif
|
||||
/* Reset cur if we allocated a new block. */
|
||||
if (arena->a_cur->ab_next) {
|
||||
arena->a_cur = arena->a_cur->ab_next;
|
||||
/* Reset cur if we allocated a new block. */
|
||||
if (arena->a_cur->ab_next) {
|
||||
arena->a_cur = arena->a_cur->ab_next;
|
||||
#if defined(Py_DEBUG)
|
||||
arena->total_blocks++;
|
||||
arena->total_block_size += arena->a_cur->ab_size;
|
||||
if (arena->a_cur->ab_size > DEFAULT_BLOCK_SIZE)
|
||||
++arena->total_big_blocks;
|
||||
arena->total_blocks++;
|
||||
arena->total_block_size += arena->a_cur->ab_size;
|
||||
if (arena->a_cur->ab_size > DEFAULT_BLOCK_SIZE)
|
||||
++arena->total_big_blocks;
|
||||
#endif
|
||||
}
|
||||
return p;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
int
|
||||
PyArena_AddPyObject(PyArena *arena, PyObject *obj)
|
||||
{
|
||||
int r = PyList_Append(arena->a_objects, obj);
|
||||
if (r >= 0) {
|
||||
Py_DECREF(obj);
|
||||
}
|
||||
return r;
|
||||
int r = PyList_Append(arena->a_objects, obj);
|
||||
if (r >= 0) {
|
||||
Py_DECREF(obj);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
|
|
@ -7,9 +7,9 @@
|
|||
thus rounding from extended precision to double precision. */
|
||||
double _Py_force_double(double x)
|
||||
{
|
||||
volatile double y;
|
||||
y = x;
|
||||
return y;
|
||||
volatile double y;
|
||||
y = x;
|
||||
return y;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -34,21 +34,21 @@ void _Py_set_387controlword(unsigned short cw) {
|
|||
#ifndef HAVE_HYPOT
|
||||
double hypot(double x, double y)
|
||||
{
|
||||
double yx;
|
||||
double yx;
|
||||
|
||||
x = fabs(x);
|
||||
y = fabs(y);
|
||||
if (x < y) {
|
||||
double temp = x;
|
||||
x = y;
|
||||
y = temp;
|
||||
}
|
||||
if (x == 0.)
|
||||
return 0.;
|
||||
else {
|
||||
yx = y/x;
|
||||
return x*sqrt(1.+yx*yx);
|
||||
}
|
||||
x = fabs(x);
|
||||
y = fabs(y);
|
||||
if (x < y) {
|
||||
double temp = x;
|
||||
x = y;
|
||||
y = temp;
|
||||
}
|
||||
if (x == 0.)
|
||||
return 0.;
|
||||
else {
|
||||
yx = y/x;
|
||||
return x*sqrt(1.+yx*yx);
|
||||
}
|
||||
}
|
||||
#endif /* HAVE_HYPOT */
|
||||
|
||||
|
@ -56,12 +56,12 @@ double hypot(double x, double y)
|
|||
double
|
||||
copysign(double x, double y)
|
||||
{
|
||||
/* use atan2 to distinguish -0. from 0. */
|
||||
if (y > 0. || (y == 0. && atan2(y, -1.) > 0.)) {
|
||||
return fabs(x);
|
||||
} else {
|
||||
return -fabs(x);
|
||||
}
|
||||
/* use atan2 to distinguish -0. from 0. */
|
||||
if (y > 0. || (y == 0. && atan2(y, -1.) > 0.)) {
|
||||
return fabs(x);
|
||||
} else {
|
||||
return -fabs(x);
|
||||
}
|
||||
}
|
||||
#endif /* HAVE_COPYSIGN */
|
||||
|
||||
|
@ -73,7 +73,7 @@ round(double x)
|
|||
absx = fabs(x);
|
||||
y = floor(absx);
|
||||
if (absx - y >= 0.5)
|
||||
y += 1.0;
|
||||
y += 1.0;
|
||||
return copysign(y, x);
|
||||
}
|
||||
#endif /* HAVE_ROUND */
|
||||
|
|
702
Python/pystate.c
702
Python/pystate.c
|
@ -58,92 +58,92 @@ static void _PyGILState_NoteThreadState(PyThreadState* tstate);
|
|||
PyInterpreterState *
|
||||
PyInterpreterState_New(void)
|
||||
{
|
||||
PyInterpreterState *interp = (PyInterpreterState *)
|
||||
malloc(sizeof(PyInterpreterState));
|
||||
PyInterpreterState *interp = (PyInterpreterState *)
|
||||
malloc(sizeof(PyInterpreterState));
|
||||
|
||||
if (interp != NULL) {
|
||||
HEAD_INIT();
|
||||
if (interp != NULL) {
|
||||
HEAD_INIT();
|
||||
#ifdef WITH_THREAD
|
||||
if (head_mutex == NULL)
|
||||
Py_FatalError("Can't initialize threads for interpreter");
|
||||
if (head_mutex == NULL)
|
||||
Py_FatalError("Can't initialize threads for interpreter");
|
||||
#endif
|
||||
interp->modules = NULL;
|
||||
interp->modules_reloading = NULL;
|
||||
interp->sysdict = NULL;
|
||||
interp->builtins = NULL;
|
||||
interp->tstate_head = NULL;
|
||||
interp->codec_search_path = NULL;
|
||||
interp->codec_search_cache = NULL;
|
||||
interp->codec_error_registry = NULL;
|
||||
interp->modules = NULL;
|
||||
interp->modules_reloading = NULL;
|
||||
interp->sysdict = NULL;
|
||||
interp->builtins = NULL;
|
||||
interp->tstate_head = NULL;
|
||||
interp->codec_search_path = NULL;
|
||||
interp->codec_search_cache = NULL;
|
||||
interp->codec_error_registry = NULL;
|
||||
#ifdef HAVE_DLOPEN
|
||||
#ifdef RTLD_NOW
|
||||
interp->dlopenflags = RTLD_NOW;
|
||||
interp->dlopenflags = RTLD_NOW;
|
||||
#else
|
||||
interp->dlopenflags = RTLD_LAZY;
|
||||
interp->dlopenflags = RTLD_LAZY;
|
||||
#endif
|
||||
#endif
|
||||
#ifdef WITH_TSC
|
||||
interp->tscdump = 0;
|
||||
interp->tscdump = 0;
|
||||
#endif
|
||||
|
||||
HEAD_LOCK();
|
||||
interp->next = interp_head;
|
||||
interp_head = interp;
|
||||
HEAD_UNLOCK();
|
||||
}
|
||||
HEAD_LOCK();
|
||||
interp->next = interp_head;
|
||||
interp_head = interp;
|
||||
HEAD_UNLOCK();
|
||||
}
|
||||
|
||||
return interp;
|
||||
return interp;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PyInterpreterState_Clear(PyInterpreterState *interp)
|
||||
{
|
||||
PyThreadState *p;
|
||||
HEAD_LOCK();
|
||||
for (p = interp->tstate_head; p != NULL; p = p->next)
|
||||
PyThreadState_Clear(p);
|
||||
HEAD_UNLOCK();
|
||||
Py_CLEAR(interp->codec_search_path);
|
||||
Py_CLEAR(interp->codec_search_cache);
|
||||
Py_CLEAR(interp->codec_error_registry);
|
||||
Py_CLEAR(interp->modules);
|
||||
Py_CLEAR(interp->modules_reloading);
|
||||
Py_CLEAR(interp->sysdict);
|
||||
Py_CLEAR(interp->builtins);
|
||||
PyThreadState *p;
|
||||
HEAD_LOCK();
|
||||
for (p = interp->tstate_head; p != NULL; p = p->next)
|
||||
PyThreadState_Clear(p);
|
||||
HEAD_UNLOCK();
|
||||
Py_CLEAR(interp->codec_search_path);
|
||||
Py_CLEAR(interp->codec_search_cache);
|
||||
Py_CLEAR(interp->codec_error_registry);
|
||||
Py_CLEAR(interp->modules);
|
||||
Py_CLEAR(interp->modules_reloading);
|
||||
Py_CLEAR(interp->sysdict);
|
||||
Py_CLEAR(interp->builtins);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
zapthreads(PyInterpreterState *interp)
|
||||
{
|
||||
PyThreadState *p;
|
||||
/* No need to lock the mutex here because this should only happen
|
||||
when the threads are all really dead (XXX famous last words). */
|
||||
while ((p = interp->tstate_head) != NULL) {
|
||||
PyThreadState_Delete(p);
|
||||
}
|
||||
PyThreadState *p;
|
||||
/* No need to lock the mutex here because this should only happen
|
||||
when the threads are all really dead (XXX famous last words). */
|
||||
while ((p = interp->tstate_head) != NULL) {
|
||||
PyThreadState_Delete(p);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PyInterpreterState_Delete(PyInterpreterState *interp)
|
||||
{
|
||||
PyInterpreterState **p;
|
||||
zapthreads(interp);
|
||||
HEAD_LOCK();
|
||||
for (p = &interp_head; ; p = &(*p)->next) {
|
||||
if (*p == NULL)
|
||||
Py_FatalError(
|
||||
"PyInterpreterState_Delete: invalid interp");
|
||||
if (*p == interp)
|
||||
break;
|
||||
}
|
||||
if (interp->tstate_head != NULL)
|
||||
Py_FatalError("PyInterpreterState_Delete: remaining threads");
|
||||
*p = interp->next;
|
||||
HEAD_UNLOCK();
|
||||
free(interp);
|
||||
PyInterpreterState **p;
|
||||
zapthreads(interp);
|
||||
HEAD_LOCK();
|
||||
for (p = &interp_head; ; p = &(*p)->next) {
|
||||
if (*p == NULL)
|
||||
Py_FatalError(
|
||||
"PyInterpreterState_Delete: invalid interp");
|
||||
if (*p == interp)
|
||||
break;
|
||||
}
|
||||
if (interp->tstate_head != NULL)
|
||||
Py_FatalError("PyInterpreterState_Delete: remaining threads");
|
||||
*p = interp->next;
|
||||
HEAD_UNLOCK();
|
||||
free(interp);
|
||||
}
|
||||
|
||||
|
||||
|
@ -151,104 +151,104 @@ PyInterpreterState_Delete(PyInterpreterState *interp)
|
|||
static struct _frame *
|
||||
threadstate_getframe(PyThreadState *self)
|
||||
{
|
||||
return self->frame;
|
||||
return self->frame;
|
||||
}
|
||||
|
||||
static PyThreadState *
|
||||
new_threadstate(PyInterpreterState *interp, int init)
|
||||
{
|
||||
PyThreadState *tstate = (PyThreadState *)malloc(sizeof(PyThreadState));
|
||||
PyThreadState *tstate = (PyThreadState *)malloc(sizeof(PyThreadState));
|
||||
|
||||
if (_PyThreadState_GetFrame == NULL)
|
||||
_PyThreadState_GetFrame = threadstate_getframe;
|
||||
if (_PyThreadState_GetFrame == NULL)
|
||||
_PyThreadState_GetFrame = threadstate_getframe;
|
||||
|
||||
if (tstate != NULL) {
|
||||
tstate->interp = interp;
|
||||
if (tstate != NULL) {
|
||||
tstate->interp = interp;
|
||||
|
||||
tstate->frame = NULL;
|
||||
tstate->recursion_depth = 0;
|
||||
tstate->tracing = 0;
|
||||
tstate->use_tracing = 0;
|
||||
tstate->tick_counter = 0;
|
||||
tstate->gilstate_counter = 0;
|
||||
tstate->async_exc = NULL;
|
||||
tstate->frame = NULL;
|
||||
tstate->recursion_depth = 0;
|
||||
tstate->tracing = 0;
|
||||
tstate->use_tracing = 0;
|
||||
tstate->tick_counter = 0;
|
||||
tstate->gilstate_counter = 0;
|
||||
tstate->async_exc = NULL;
|
||||
#ifdef WITH_THREAD
|
||||
tstate->thread_id = PyThread_get_thread_ident();
|
||||
tstate->thread_id = PyThread_get_thread_ident();
|
||||
#else
|
||||
tstate->thread_id = 0;
|
||||
tstate->thread_id = 0;
|
||||
#endif
|
||||
|
||||
tstate->dict = NULL;
|
||||
tstate->dict = NULL;
|
||||
|
||||
tstate->curexc_type = NULL;
|
||||
tstate->curexc_value = NULL;
|
||||
tstate->curexc_traceback = NULL;
|
||||
tstate->curexc_type = NULL;
|
||||
tstate->curexc_value = NULL;
|
||||
tstate->curexc_traceback = NULL;
|
||||
|
||||
tstate->exc_type = NULL;
|
||||
tstate->exc_value = NULL;
|
||||
tstate->exc_traceback = NULL;
|
||||
tstate->exc_type = NULL;
|
||||
tstate->exc_value = NULL;
|
||||
tstate->exc_traceback = NULL;
|
||||
|
||||
tstate->c_profilefunc = NULL;
|
||||
tstate->c_tracefunc = NULL;
|
||||
tstate->c_profileobj = NULL;
|
||||
tstate->c_traceobj = NULL;
|
||||
tstate->c_profilefunc = NULL;
|
||||
tstate->c_tracefunc = NULL;
|
||||
tstate->c_profileobj = NULL;
|
||||
tstate->c_traceobj = NULL;
|
||||
|
||||
if (init)
|
||||
_PyThreadState_Init(tstate);
|
||||
if (init)
|
||||
_PyThreadState_Init(tstate);
|
||||
|
||||
HEAD_LOCK();
|
||||
tstate->next = interp->tstate_head;
|
||||
interp->tstate_head = tstate;
|
||||
HEAD_UNLOCK();
|
||||
}
|
||||
HEAD_LOCK();
|
||||
tstate->next = interp->tstate_head;
|
||||
interp->tstate_head = tstate;
|
||||
HEAD_UNLOCK();
|
||||
}
|
||||
|
||||
return tstate;
|
||||
return tstate;
|
||||
}
|
||||
|
||||
PyThreadState *
|
||||
PyThreadState_New(PyInterpreterState *interp)
|
||||
{
|
||||
return new_threadstate(interp, 1);
|
||||
return new_threadstate(interp, 1);
|
||||
}
|
||||
|
||||
PyThreadState *
|
||||
_PyThreadState_Prealloc(PyInterpreterState *interp)
|
||||
{
|
||||
return new_threadstate(interp, 0);
|
||||
return new_threadstate(interp, 0);
|
||||
}
|
||||
|
||||
void
|
||||
_PyThreadState_Init(PyThreadState *tstate)
|
||||
{
|
||||
#ifdef WITH_THREAD
|
||||
_PyGILState_NoteThreadState(tstate);
|
||||
_PyGILState_NoteThreadState(tstate);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
PyThreadState_Clear(PyThreadState *tstate)
|
||||
{
|
||||
if (Py_VerboseFlag && tstate->frame != NULL)
|
||||
fprintf(stderr,
|
||||
"PyThreadState_Clear: warning: thread still has a frame\n");
|
||||
if (Py_VerboseFlag && tstate->frame != NULL)
|
||||
fprintf(stderr,
|
||||
"PyThreadState_Clear: warning: thread still has a frame\n");
|
||||
|
||||
Py_CLEAR(tstate->frame);
|
||||
Py_CLEAR(tstate->frame);
|
||||
|
||||
Py_CLEAR(tstate->dict);
|
||||
Py_CLEAR(tstate->async_exc);
|
||||
Py_CLEAR(tstate->dict);
|
||||
Py_CLEAR(tstate->async_exc);
|
||||
|
||||
Py_CLEAR(tstate->curexc_type);
|
||||
Py_CLEAR(tstate->curexc_value);
|
||||
Py_CLEAR(tstate->curexc_traceback);
|
||||
Py_CLEAR(tstate->curexc_type);
|
||||
Py_CLEAR(tstate->curexc_value);
|
||||
Py_CLEAR(tstate->curexc_traceback);
|
||||
|
||||
Py_CLEAR(tstate->exc_type);
|
||||
Py_CLEAR(tstate->exc_value);
|
||||
Py_CLEAR(tstate->exc_traceback);
|
||||
Py_CLEAR(tstate->exc_type);
|
||||
Py_CLEAR(tstate->exc_value);
|
||||
Py_CLEAR(tstate->exc_traceback);
|
||||
|
||||
tstate->c_profilefunc = NULL;
|
||||
tstate->c_tracefunc = NULL;
|
||||
Py_CLEAR(tstate->c_profileobj);
|
||||
Py_CLEAR(tstate->c_traceobj);
|
||||
tstate->c_profilefunc = NULL;
|
||||
tstate->c_tracefunc = NULL;
|
||||
Py_CLEAR(tstate->c_profileobj);
|
||||
Py_CLEAR(tstate->c_traceobj);
|
||||
}
|
||||
|
||||
|
||||
|
@ -256,50 +256,50 @@ PyThreadState_Clear(PyThreadState *tstate)
|
|||
static void
|
||||
tstate_delete_common(PyThreadState *tstate)
|
||||
{
|
||||
PyInterpreterState *interp;
|
||||
PyThreadState **p;
|
||||
PyThreadState *prev_p = NULL;
|
||||
if (tstate == NULL)
|
||||
Py_FatalError("PyThreadState_Delete: NULL tstate");
|
||||
interp = tstate->interp;
|
||||
if (interp == NULL)
|
||||
Py_FatalError("PyThreadState_Delete: NULL interp");
|
||||
HEAD_LOCK();
|
||||
for (p = &interp->tstate_head; ; p = &(*p)->next) {
|
||||
if (*p == NULL)
|
||||
Py_FatalError(
|
||||
"PyThreadState_Delete: invalid tstate");
|
||||
if (*p == tstate)
|
||||
break;
|
||||
/* Sanity check. These states should never happen but if
|
||||
* they do we must abort. Otherwise we'll end up spinning in
|
||||
* in a tight loop with the lock held. A similar check is done
|
||||
* in thread.c find_key(). */
|
||||
if (*p == prev_p)
|
||||
Py_FatalError(
|
||||
"PyThreadState_Delete: small circular list(!)"
|
||||
" and tstate not found.");
|
||||
prev_p = *p;
|
||||
if ((*p)->next == interp->tstate_head)
|
||||
Py_FatalError(
|
||||
"PyThreadState_Delete: circular list(!) and"
|
||||
" tstate not found.");
|
||||
}
|
||||
*p = tstate->next;
|
||||
HEAD_UNLOCK();
|
||||
free(tstate);
|
||||
PyInterpreterState *interp;
|
||||
PyThreadState **p;
|
||||
PyThreadState *prev_p = NULL;
|
||||
if (tstate == NULL)
|
||||
Py_FatalError("PyThreadState_Delete: NULL tstate");
|
||||
interp = tstate->interp;
|
||||
if (interp == NULL)
|
||||
Py_FatalError("PyThreadState_Delete: NULL interp");
|
||||
HEAD_LOCK();
|
||||
for (p = &interp->tstate_head; ; p = &(*p)->next) {
|
||||
if (*p == NULL)
|
||||
Py_FatalError(
|
||||
"PyThreadState_Delete: invalid tstate");
|
||||
if (*p == tstate)
|
||||
break;
|
||||
/* Sanity check. These states should never happen but if
|
||||
* they do we must abort. Otherwise we'll end up spinning in
|
||||
* in a tight loop with the lock held. A similar check is done
|
||||
* in thread.c find_key(). */
|
||||
if (*p == prev_p)
|
||||
Py_FatalError(
|
||||
"PyThreadState_Delete: small circular list(!)"
|
||||
" and tstate not found.");
|
||||
prev_p = *p;
|
||||
if ((*p)->next == interp->tstate_head)
|
||||
Py_FatalError(
|
||||
"PyThreadState_Delete: circular list(!) and"
|
||||
" tstate not found.");
|
||||
}
|
||||
*p = tstate->next;
|
||||
HEAD_UNLOCK();
|
||||
free(tstate);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PyThreadState_Delete(PyThreadState *tstate)
|
||||
{
|
||||
if (tstate == _PyThreadState_Current)
|
||||
Py_FatalError("PyThreadState_Delete: tstate is still current");
|
||||
tstate_delete_common(tstate);
|
||||
if (tstate == _PyThreadState_Current)
|
||||
Py_FatalError("PyThreadState_Delete: tstate is still current");
|
||||
tstate_delete_common(tstate);
|
||||
#ifdef WITH_THREAD
|
||||
if (autoTLSkey && PyThread_get_key_value(autoTLSkey) == tstate)
|
||||
PyThread_delete_key_value(autoTLSkey);
|
||||
if (autoTLSkey && PyThread_get_key_value(autoTLSkey) == tstate)
|
||||
PyThread_delete_key_value(autoTLSkey);
|
||||
#endif /* WITH_THREAD */
|
||||
}
|
||||
|
||||
|
@ -308,15 +308,15 @@ PyThreadState_Delete(PyThreadState *tstate)
|
|||
void
|
||||
PyThreadState_DeleteCurrent()
|
||||
{
|
||||
PyThreadState *tstate = _PyThreadState_Current;
|
||||
if (tstate == NULL)
|
||||
Py_FatalError(
|
||||
"PyThreadState_DeleteCurrent: no current tstate");
|
||||
_PyThreadState_Current = NULL;
|
||||
tstate_delete_common(tstate);
|
||||
if (autoTLSkey && PyThread_get_key_value(autoTLSkey) == tstate)
|
||||
PyThread_delete_key_value(autoTLSkey);
|
||||
PyEval_ReleaseLock();
|
||||
PyThreadState *tstate = _PyThreadState_Current;
|
||||
if (tstate == NULL)
|
||||
Py_FatalError(
|
||||
"PyThreadState_DeleteCurrent: no current tstate");
|
||||
_PyThreadState_Current = NULL;
|
||||
tstate_delete_common(tstate);
|
||||
if (autoTLSkey && PyThread_get_key_value(autoTLSkey) == tstate)
|
||||
PyThread_delete_key_value(autoTLSkey);
|
||||
PyEval_ReleaseLock();
|
||||
}
|
||||
#endif /* WITH_THREAD */
|
||||
|
||||
|
@ -324,36 +324,36 @@ PyThreadState_DeleteCurrent()
|
|||
PyThreadState *
|
||||
PyThreadState_Get(void)
|
||||
{
|
||||
if (_PyThreadState_Current == NULL)
|
||||
Py_FatalError("PyThreadState_Get: no current thread");
|
||||
if (_PyThreadState_Current == NULL)
|
||||
Py_FatalError("PyThreadState_Get: no current thread");
|
||||
|
||||
return _PyThreadState_Current;
|
||||
return _PyThreadState_Current;
|
||||
}
|
||||
|
||||
|
||||
PyThreadState *
|
||||
PyThreadState_Swap(PyThreadState *newts)
|
||||
{
|
||||
PyThreadState *oldts = _PyThreadState_Current;
|
||||
PyThreadState *oldts = _PyThreadState_Current;
|
||||
|
||||
_PyThreadState_Current = newts;
|
||||
/* It should not be possible for more than one thread state
|
||||
to be used for a thread. Check this the best we can in debug
|
||||
builds.
|
||||
*/
|
||||
_PyThreadState_Current = newts;
|
||||
/* It should not be possible for more than one thread state
|
||||
to be used for a thread. Check this the best we can in debug
|
||||
builds.
|
||||
*/
|
||||
#if defined(Py_DEBUG) && defined(WITH_THREAD)
|
||||
if (newts) {
|
||||
/* This can be called from PyEval_RestoreThread(). Similar
|
||||
to it, we need to ensure errno doesn't change.
|
||||
*/
|
||||
int err = errno;
|
||||
PyThreadState *check = PyGILState_GetThisThreadState();
|
||||
if (check && check->interp == newts->interp && check != newts)
|
||||
Py_FatalError("Invalid thread state for this thread");
|
||||
errno = err;
|
||||
}
|
||||
if (newts) {
|
||||
/* This can be called from PyEval_RestoreThread(). Similar
|
||||
to it, we need to ensure errno doesn't change.
|
||||
*/
|
||||
int err = errno;
|
||||
PyThreadState *check = PyGILState_GetThisThreadState();
|
||||
if (check && check->interp == newts->interp && check != newts)
|
||||
Py_FatalError("Invalid thread state for this thread");
|
||||
errno = err;
|
||||
}
|
||||
#endif
|
||||
return oldts;
|
||||
return oldts;
|
||||
}
|
||||
|
||||
/* An extension mechanism to store arbitrary additional per-thread state.
|
||||
|
@ -365,16 +365,16 @@ PyThreadState_Swap(PyThreadState *newts)
|
|||
PyObject *
|
||||
PyThreadState_GetDict(void)
|
||||
{
|
||||
if (_PyThreadState_Current == NULL)
|
||||
return NULL;
|
||||
if (_PyThreadState_Current == NULL)
|
||||
return NULL;
|
||||
|
||||
if (_PyThreadState_Current->dict == NULL) {
|
||||
PyObject *d;
|
||||
_PyThreadState_Current->dict = d = PyDict_New();
|
||||
if (d == NULL)
|
||||
PyErr_Clear();
|
||||
}
|
||||
return _PyThreadState_Current->dict;
|
||||
if (_PyThreadState_Current->dict == NULL) {
|
||||
PyObject *d;
|
||||
_PyThreadState_Current->dict = d = PyDict_New();
|
||||
if (d == NULL)
|
||||
PyErr_Clear();
|
||||
}
|
||||
return _PyThreadState_Current->dict;
|
||||
}
|
||||
|
||||
|
||||
|
@ -388,36 +388,36 @@ PyThreadState_GetDict(void)
|
|||
|
||||
int
|
||||
PyThreadState_SetAsyncExc(long id, PyObject *exc) {
|
||||
PyThreadState *tstate = PyThreadState_GET();
|
||||
PyInterpreterState *interp = tstate->interp;
|
||||
PyThreadState *p;
|
||||
PyThreadState *tstate = PyThreadState_GET();
|
||||
PyInterpreterState *interp = tstate->interp;
|
||||
PyThreadState *p;
|
||||
|
||||
/* Although the GIL is held, a few C API functions can be called
|
||||
* without the GIL held, and in particular some that create and
|
||||
* destroy thread and interpreter states. Those can mutate the
|
||||
* list of thread states we're traversing, so to prevent that we lock
|
||||
* head_mutex for the duration.
|
||||
*/
|
||||
HEAD_LOCK();
|
||||
for (p = interp->tstate_head; p != NULL; p = p->next) {
|
||||
if (p->thread_id == id) {
|
||||
/* Tricky: we need to decref the current value
|
||||
* (if any) in p->async_exc, but that can in turn
|
||||
* allow arbitrary Python code to run, including
|
||||
* perhaps calls to this function. To prevent
|
||||
* deadlock, we need to release head_mutex before
|
||||
* the decref.
|
||||
*/
|
||||
PyObject *old_exc = p->async_exc;
|
||||
Py_XINCREF(exc);
|
||||
p->async_exc = exc;
|
||||
HEAD_UNLOCK();
|
||||
Py_XDECREF(old_exc);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
HEAD_UNLOCK();
|
||||
return 0;
|
||||
/* Although the GIL is held, a few C API functions can be called
|
||||
* without the GIL held, and in particular some that create and
|
||||
* destroy thread and interpreter states. Those can mutate the
|
||||
* list of thread states we're traversing, so to prevent that we lock
|
||||
* head_mutex for the duration.
|
||||
*/
|
||||
HEAD_LOCK();
|
||||
for (p = interp->tstate_head; p != NULL; p = p->next) {
|
||||
if (p->thread_id == id) {
|
||||
/* Tricky: we need to decref the current value
|
||||
* (if any) in p->async_exc, but that can in turn
|
||||
* allow arbitrary Python code to run, including
|
||||
* perhaps calls to this function. To prevent
|
||||
* deadlock, we need to release head_mutex before
|
||||
* the decref.
|
||||
*/
|
||||
PyObject *old_exc = p->async_exc;
|
||||
Py_XINCREF(exc);
|
||||
p->async_exc = exc;
|
||||
HEAD_UNLOCK();
|
||||
Py_XDECREF(old_exc);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
HEAD_UNLOCK();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -427,22 +427,22 @@ PyThreadState_SetAsyncExc(long id, PyObject *exc) {
|
|||
PyInterpreterState *
|
||||
PyInterpreterState_Head(void)
|
||||
{
|
||||
return interp_head;
|
||||
return interp_head;
|
||||
}
|
||||
|
||||
PyInterpreterState *
|
||||
PyInterpreterState_Next(PyInterpreterState *interp) {
|
||||
return interp->next;
|
||||
return interp->next;
|
||||
}
|
||||
|
||||
PyThreadState *
|
||||
PyInterpreterState_ThreadHead(PyInterpreterState *interp) {
|
||||
return interp->tstate_head;
|
||||
return interp->tstate_head;
|
||||
}
|
||||
|
||||
PyThreadState *
|
||||
PyThreadState_Next(PyThreadState *tstate) {
|
||||
return tstate->next;
|
||||
return tstate->next;
|
||||
}
|
||||
|
||||
/* The implementation of sys._current_frames(). This is intended to be
|
||||
|
@ -453,44 +453,44 @@ PyThreadState_Next(PyThreadState *tstate) {
|
|||
PyObject *
|
||||
_PyThread_CurrentFrames(void)
|
||||
{
|
||||
PyObject *result;
|
||||
PyInterpreterState *i;
|
||||
PyObject *result;
|
||||
PyInterpreterState *i;
|
||||
|
||||
result = PyDict_New();
|
||||
if (result == NULL)
|
||||
return NULL;
|
||||
result = PyDict_New();
|
||||
if (result == NULL)
|
||||
return NULL;
|
||||
|
||||
/* for i in all interpreters:
|
||||
* for t in all of i's thread states:
|
||||
* if t's frame isn't NULL, map t's id to its frame
|
||||
* Because these lists can mutute even when the GIL is held, we
|
||||
* need to grab head_mutex for the duration.
|
||||
*/
|
||||
HEAD_LOCK();
|
||||
for (i = interp_head; i != NULL; i = i->next) {
|
||||
PyThreadState *t;
|
||||
for (t = i->tstate_head; t != NULL; t = t->next) {
|
||||
PyObject *id;
|
||||
int stat;
|
||||
struct _frame *frame = t->frame;
|
||||
if (frame == NULL)
|
||||
continue;
|
||||
id = PyInt_FromLong(t->thread_id);
|
||||
if (id == NULL)
|
||||
goto Fail;
|
||||
stat = PyDict_SetItem(result, id, (PyObject *)frame);
|
||||
Py_DECREF(id);
|
||||
if (stat < 0)
|
||||
goto Fail;
|
||||
}
|
||||
}
|
||||
HEAD_UNLOCK();
|
||||
return result;
|
||||
/* for i in all interpreters:
|
||||
* for t in all of i's thread states:
|
||||
* if t's frame isn't NULL, map t's id to its frame
|
||||
* Because these lists can mutute even when the GIL is held, we
|
||||
* need to grab head_mutex for the duration.
|
||||
*/
|
||||
HEAD_LOCK();
|
||||
for (i = interp_head; i != NULL; i = i->next) {
|
||||
PyThreadState *t;
|
||||
for (t = i->tstate_head; t != NULL; t = t->next) {
|
||||
PyObject *id;
|
||||
int stat;
|
||||
struct _frame *frame = t->frame;
|
||||
if (frame == NULL)
|
||||
continue;
|
||||
id = PyInt_FromLong(t->thread_id);
|
||||
if (id == NULL)
|
||||
goto Fail;
|
||||
stat = PyDict_SetItem(result, id, (PyObject *)frame);
|
||||
Py_DECREF(id);
|
||||
if (stat < 0)
|
||||
goto Fail;
|
||||
}
|
||||
}
|
||||
HEAD_UNLOCK();
|
||||
return result;
|
||||
|
||||
Fail:
|
||||
HEAD_UNLOCK();
|
||||
Py_DECREF(result);
|
||||
return NULL;
|
||||
HEAD_UNLOCK();
|
||||
Py_DECREF(result);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Python "auto thread state" API. */
|
||||
|
@ -507,12 +507,12 @@ _PyThread_CurrentFrames(void)
|
|||
static int
|
||||
PyThreadState_IsCurrent(PyThreadState *tstate)
|
||||
{
|
||||
/* Must be the tstate for this thread */
|
||||
assert(PyGILState_GetThisThreadState()==tstate);
|
||||
/* On Windows at least, simple reads and writes to 32 bit values
|
||||
are atomic.
|
||||
*/
|
||||
return tstate == _PyThreadState_Current;
|
||||
/* Must be the tstate for this thread */
|
||||
assert(PyGILState_GetThisThreadState()==tstate);
|
||||
/* On Windows at least, simple reads and writes to 32 bit values
|
||||
are atomic.
|
||||
*/
|
||||
return tstate == _PyThreadState_Current;
|
||||
}
|
||||
|
||||
/* Internal initialization/finalization functions called by
|
||||
|
@ -521,21 +521,21 @@ PyThreadState_IsCurrent(PyThreadState *tstate)
|
|||
void
|
||||
_PyGILState_Init(PyInterpreterState *i, PyThreadState *t)
|
||||
{
|
||||
assert(i && t); /* must init with valid states */
|
||||
autoTLSkey = PyThread_create_key();
|
||||
autoInterpreterState = i;
|
||||
assert(PyThread_get_key_value(autoTLSkey) == NULL);
|
||||
assert(t->gilstate_counter == 0);
|
||||
assert(i && t); /* must init with valid states */
|
||||
autoTLSkey = PyThread_create_key();
|
||||
autoInterpreterState = i;
|
||||
assert(PyThread_get_key_value(autoTLSkey) == NULL);
|
||||
assert(t->gilstate_counter == 0);
|
||||
|
||||
_PyGILState_NoteThreadState(t);
|
||||
_PyGILState_NoteThreadState(t);
|
||||
}
|
||||
|
||||
void
|
||||
_PyGILState_Fini(void)
|
||||
{
|
||||
PyThread_delete_key(autoTLSkey);
|
||||
autoTLSkey = 0;
|
||||
autoInterpreterState = NULL;
|
||||
PyThread_delete_key(autoTLSkey);
|
||||
autoTLSkey = 0;
|
||||
autoInterpreterState = NULL;
|
||||
}
|
||||
|
||||
/* When a thread state is created for a thread by some mechanism other than
|
||||
|
@ -546,113 +546,113 @@ _PyGILState_Fini(void)
|
|||
static void
|
||||
_PyGILState_NoteThreadState(PyThreadState* tstate)
|
||||
{
|
||||
/* If autoTLSkey is 0, this must be the very first threadstate created
|
||||
in Py_Initialize(). Don't do anything for now (we'll be back here
|
||||
when _PyGILState_Init is called). */
|
||||
if (!autoTLSkey)
|
||||
return;
|
||||
/* If autoTLSkey is 0, this must be the very first threadstate created
|
||||
in Py_Initialize(). Don't do anything for now (we'll be back here
|
||||
when _PyGILState_Init is called). */
|
||||
if (!autoTLSkey)
|
||||
return;
|
||||
|
||||
/* Stick the thread state for this thread in thread local storage.
|
||||
/* Stick the thread state for this thread in thread local storage.
|
||||
|
||||
The only situation where you can legitimately have more than one
|
||||
thread state for an OS level thread is when there are multiple
|
||||
interpreters, when:
|
||||
The only situation where you can legitimately have more than one
|
||||
thread state for an OS level thread is when there are multiple
|
||||
interpreters, when:
|
||||
|
||||
a) You shouldn't really be using the PyGILState_ APIs anyway,
|
||||
and:
|
||||
a) You shouldn't really be using the PyGILState_ APIs anyway,
|
||||
and:
|
||||
|
||||
b) The slightly odd way PyThread_set_key_value works (see
|
||||
comments by its implementation) means that the first thread
|
||||
state created for that given OS level thread will "win",
|
||||
which seems reasonable behaviour.
|
||||
*/
|
||||
if (PyThread_set_key_value(autoTLSkey, (void *)tstate) < 0)
|
||||
Py_FatalError("Couldn't create autoTLSkey mapping");
|
||||
b) The slightly odd way PyThread_set_key_value works (see
|
||||
comments by its implementation) means that the first thread
|
||||
state created for that given OS level thread will "win",
|
||||
which seems reasonable behaviour.
|
||||
*/
|
||||
if (PyThread_set_key_value(autoTLSkey, (void *)tstate) < 0)
|
||||
Py_FatalError("Couldn't create autoTLSkey mapping");
|
||||
|
||||
/* PyGILState_Release must not try to delete this thread state. */
|
||||
tstate->gilstate_counter = 1;
|
||||
/* PyGILState_Release must not try to delete this thread state. */
|
||||
tstate->gilstate_counter = 1;
|
||||
}
|
||||
|
||||
/* The public functions */
|
||||
PyThreadState *
|
||||
PyGILState_GetThisThreadState(void)
|
||||
{
|
||||
if (autoInterpreterState == NULL || autoTLSkey == 0)
|
||||
return NULL;
|
||||
return (PyThreadState *)PyThread_get_key_value(autoTLSkey);
|
||||
if (autoInterpreterState == NULL || autoTLSkey == 0)
|
||||
return NULL;
|
||||
return (PyThreadState *)PyThread_get_key_value(autoTLSkey);
|
||||
}
|
||||
|
||||
PyGILState_STATE
|
||||
PyGILState_Ensure(void)
|
||||
{
|
||||
int current;
|
||||
PyThreadState *tcur;
|
||||
/* Note that we do not auto-init Python here - apart from
|
||||
potential races with 2 threads auto-initializing, pep-311
|
||||
spells out other issues. Embedders are expected to have
|
||||
called Py_Initialize() and usually PyEval_InitThreads().
|
||||
*/
|
||||
assert(autoInterpreterState); /* Py_Initialize() hasn't been called! */
|
||||
tcur = (PyThreadState *)PyThread_get_key_value(autoTLSkey);
|
||||
if (tcur == NULL) {
|
||||
/* Create a new thread state for this thread */
|
||||
tcur = PyThreadState_New(autoInterpreterState);
|
||||
if (tcur == NULL)
|
||||
Py_FatalError("Couldn't create thread-state for new thread");
|
||||
/* This is our thread state! We'll need to delete it in the
|
||||
matching call to PyGILState_Release(). */
|
||||
tcur->gilstate_counter = 0;
|
||||
current = 0; /* new thread state is never current */
|
||||
}
|
||||
else
|
||||
current = PyThreadState_IsCurrent(tcur);
|
||||
if (current == 0)
|
||||
PyEval_RestoreThread(tcur);
|
||||
/* Update our counter in the thread-state - no need for locks:
|
||||
- tcur will remain valid as we hold the GIL.
|
||||
- the counter is safe as we are the only thread "allowed"
|
||||
to modify this value
|
||||
*/
|
||||
++tcur->gilstate_counter;
|
||||
return current ? PyGILState_LOCKED : PyGILState_UNLOCKED;
|
||||
int current;
|
||||
PyThreadState *tcur;
|
||||
/* Note that we do not auto-init Python here - apart from
|
||||
potential races with 2 threads auto-initializing, pep-311
|
||||
spells out other issues. Embedders are expected to have
|
||||
called Py_Initialize() and usually PyEval_InitThreads().
|
||||
*/
|
||||
assert(autoInterpreterState); /* Py_Initialize() hasn't been called! */
|
||||
tcur = (PyThreadState *)PyThread_get_key_value(autoTLSkey);
|
||||
if (tcur == NULL) {
|
||||
/* Create a new thread state for this thread */
|
||||
tcur = PyThreadState_New(autoInterpreterState);
|
||||
if (tcur == NULL)
|
||||
Py_FatalError("Couldn't create thread-state for new thread");
|
||||
/* This is our thread state! We'll need to delete it in the
|
||||
matching call to PyGILState_Release(). */
|
||||
tcur->gilstate_counter = 0;
|
||||
current = 0; /* new thread state is never current */
|
||||
}
|
||||
else
|
||||
current = PyThreadState_IsCurrent(tcur);
|
||||
if (current == 0)
|
||||
PyEval_RestoreThread(tcur);
|
||||
/* Update our counter in the thread-state - no need for locks:
|
||||
- tcur will remain valid as we hold the GIL.
|
||||
- the counter is safe as we are the only thread "allowed"
|
||||
to modify this value
|
||||
*/
|
||||
++tcur->gilstate_counter;
|
||||
return current ? PyGILState_LOCKED : PyGILState_UNLOCKED;
|
||||
}
|
||||
|
||||
void
|
||||
PyGILState_Release(PyGILState_STATE oldstate)
|
||||
{
|
||||
PyThreadState *tcur = (PyThreadState *)PyThread_get_key_value(
|
||||
autoTLSkey);
|
||||
if (tcur == NULL)
|
||||
Py_FatalError("auto-releasing thread-state, "
|
||||
"but no thread-state for this thread");
|
||||
/* We must hold the GIL and have our thread state current */
|
||||
/* XXX - remove the check - the assert should be fine,
|
||||
but while this is very new (April 2003), the extra check
|
||||
by release-only users can't hurt.
|
||||
*/
|
||||
if (! PyThreadState_IsCurrent(tcur))
|
||||
Py_FatalError("This thread state must be current when releasing");
|
||||
assert(PyThreadState_IsCurrent(tcur));
|
||||
--tcur->gilstate_counter;
|
||||
assert(tcur->gilstate_counter >= 0); /* illegal counter value */
|
||||
PyThreadState *tcur = (PyThreadState *)PyThread_get_key_value(
|
||||
autoTLSkey);
|
||||
if (tcur == NULL)
|
||||
Py_FatalError("auto-releasing thread-state, "
|
||||
"but no thread-state for this thread");
|
||||
/* We must hold the GIL and have our thread state current */
|
||||
/* XXX - remove the check - the assert should be fine,
|
||||
but while this is very new (April 2003), the extra check
|
||||
by release-only users can't hurt.
|
||||
*/
|
||||
if (! PyThreadState_IsCurrent(tcur))
|
||||
Py_FatalError("This thread state must be current when releasing");
|
||||
assert(PyThreadState_IsCurrent(tcur));
|
||||
--tcur->gilstate_counter;
|
||||
assert(tcur->gilstate_counter >= 0); /* illegal counter value */
|
||||
|
||||
/* If we're going to destroy this thread-state, we must
|
||||
* clear it while the GIL is held, as destructors may run.
|
||||
*/
|
||||
if (tcur->gilstate_counter == 0) {
|
||||
/* can't have been locked when we created it */
|
||||
assert(oldstate == PyGILState_UNLOCKED);
|
||||
PyThreadState_Clear(tcur);
|
||||
/* Delete the thread-state. Note this releases the GIL too!
|
||||
* It's vital that the GIL be held here, to avoid shutdown
|
||||
* races; see bugs 225673 and 1061968 (that nasty bug has a
|
||||
* habit of coming back).
|
||||
*/
|
||||
PyThreadState_DeleteCurrent();
|
||||
}
|
||||
/* Release the lock if necessary */
|
||||
else if (oldstate == PyGILState_UNLOCKED)
|
||||
PyEval_SaveThread();
|
||||
/* If we're going to destroy this thread-state, we must
|
||||
* clear it while the GIL is held, as destructors may run.
|
||||
*/
|
||||
if (tcur->gilstate_counter == 0) {
|
||||
/* can't have been locked when we created it */
|
||||
assert(oldstate == PyGILState_UNLOCKED);
|
||||
PyThreadState_Clear(tcur);
|
||||
/* Delete the thread-state. Note this releases the GIL too!
|
||||
* It's vital that the GIL be held here, to avoid shutdown
|
||||
* races; see bugs 225673 and 1061968 (that nasty bug has a
|
||||
* habit of coming back).
|
||||
*/
|
||||
PyThreadState_DeleteCurrent();
|
||||
}
|
||||
/* Release the lock if necessary */
|
||||
else if (oldstate == PyGILState_UNLOCKED)
|
||||
PyEval_SaveThread();
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -6,21 +6,21 @@
|
|||
int
|
||||
PyOS_mystrnicmp(const char *s1, const char *s2, Py_ssize_t size)
|
||||
{
|
||||
if (size == 0)
|
||||
return 0;
|
||||
while ((--size > 0) &&
|
||||
(tolower((unsigned)*s1) == tolower((unsigned)*s2))) {
|
||||
if (!*s1++ || !*s2++)
|
||||
break;
|
||||
}
|
||||
return tolower((unsigned)*s1) - tolower((unsigned)*s2);
|
||||
if (size == 0)
|
||||
return 0;
|
||||
while ((--size > 0) &&
|
||||
(tolower((unsigned)*s1) == tolower((unsigned)*s2))) {
|
||||
if (!*s1++ || !*s2++)
|
||||
break;
|
||||
}
|
||||
return tolower((unsigned)*s1) - tolower((unsigned)*s2);
|
||||
}
|
||||
|
||||
int
|
||||
PyOS_mystricmp(const char *s1, const char *s2)
|
||||
{
|
||||
while (*s1 && (tolower((unsigned)*s1++) == tolower((unsigned)*s2++))) {
|
||||
;
|
||||
}
|
||||
return (tolower((unsigned)*s1) - tolower((unsigned)*s2));
|
||||
while (*s1 && (tolower((unsigned)*s1++) == tolower((unsigned)*s2++))) {
|
||||
;
|
||||
}
|
||||
return (tolower((unsigned)*s1) - tolower((unsigned)*s2));
|
||||
}
|
||||
|
|
1746
Python/pystrtod.c
1746
Python/pystrtod.c
File diff suppressed because it is too large
Load diff
2530
Python/pythonrun.c
2530
Python/pythonrun.c
File diff suppressed because it is too large
Load diff
206
Python/strtod.c
206
Python/strtod.c
|
@ -25,9 +25,9 @@
|
|||
|
||||
There are two reasons why this should be provided to the net:
|
||||
(a) some UNIX systems do not yet have strtod(), or do not have it
|
||||
available in the BSD "universe" (but they do have atof()).
|
||||
available in the BSD "universe" (but they do have atof()).
|
||||
(b) some of the UNIX systems that *do* have it get it wrong.
|
||||
(some crash with large arguments, some assign the wrong *ptr value).
|
||||
(some crash with large arguments, some assign the wrong *ptr value).
|
||||
There is a reason why *we* are providing it: we need a correct version
|
||||
of strtod(), and if we give this one away maybe someone will look for
|
||||
mistakes in it and fix them for us (:-).
|
||||
|
@ -35,8 +35,8 @@
|
|||
|
||||
/* The following constants are machine-specific. MD{MIN,MAX}EXPT are
|
||||
integers and MD{MIN,MAX}FRAC are strings such that
|
||||
0.${MDMAXFRAC}e${MDMAXEXPT} is the largest representable double,
|
||||
0.${MDMINFRAC}e${MDMINEXPT} is the smallest representable +ve double
|
||||
0.${MDMAXFRAC}e${MDMAXEXPT} is the largest representable double,
|
||||
0.${MDMINFRAC}e${MDMINEXPT} is the smallest representable +ve double
|
||||
MD{MIN,MAX}FRAC must not have any trailing zeros.
|
||||
The values here are for IEEE-754 64-bit floats.
|
||||
It is not perfectly clear to me whether an IEEE infinity should be
|
||||
|
@ -47,113 +47,113 @@
|
|||
I do know about <values.h>, but the whole point of this file is that
|
||||
we can't always trust that stuff to be there or to be correct.
|
||||
*/
|
||||
static int MDMINEXPT = -323;
|
||||
static char MDMINFRAC[] = "494065645841246544";
|
||||
static double ZERO = 0.0;
|
||||
static int MDMINEXPT = -323;
|
||||
static char MDMINFRAC[] = "494065645841246544";
|
||||
static double ZERO = 0.0;
|
||||
|
||||
static int MDMAXEXPT = 309;
|
||||
static char MDMAXFRAC[] = "17976931348623157";
|
||||
static double HUGE = 1.7976931348623157e308;
|
||||
static int MDMAXEXPT = 309;
|
||||
static char MDMAXFRAC[] = "17976931348623157";
|
||||
static double HUGE = 1.7976931348623157e308;
|
||||
|
||||
extern double atof(const char *); /* Only called when result known to be ok */
|
||||
extern double atof(const char *); /* Only called when result known to be ok */
|
||||
|
||||
#ifdef HAVE_ERRNO_H
|
||||
#include <errno.h>
|
||||
#endif
|
||||
extern int errno;
|
||||
extern int errno;
|
||||
|
||||
double strtod(char *str, char **ptr)
|
||||
{
|
||||
int sign, scale, dotseen;
|
||||
int esign, expt;
|
||||
char *save;
|
||||
register char *sp, *dp;
|
||||
register int c;
|
||||
char *buforg, *buflim;
|
||||
char buffer[64]; /* 45-digit significant + */
|
||||
/* 13-digit exponent */
|
||||
sp = str;
|
||||
while (*sp == ' ') sp++;
|
||||
sign = 1;
|
||||
if (*sp == '-') sign -= 2, sp++;
|
||||
dotseen = 0, scale = 0;
|
||||
dp = buffer;
|
||||
*dp++ = '0'; *dp++ = '.';
|
||||
buforg = dp, buflim = buffer+48;
|
||||
for (save = sp; (c = *sp); sp++)
|
||||
if (c == '.') {
|
||||
if (dotseen) break;
|
||||
dotseen++;
|
||||
} else
|
||||
if ((unsigned)(c-'0') > (unsigned)('9'-'0')) {
|
||||
break;
|
||||
} else
|
||||
if (c == '0') {
|
||||
if (dp != buforg) {
|
||||
/* This is not the first digit, so we want to keep it */
|
||||
if (dp < buflim) *dp++ = c;
|
||||
if (!dotseen) scale++;
|
||||
} else {
|
||||
/* No non-zero digits seen yet */
|
||||
/* If a . has been seen, scale must be adjusted */
|
||||
if (dotseen) scale--;
|
||||
}
|
||||
} else {
|
||||
/* This is a nonzero digit, so we want to keep it */
|
||||
if (dp < buflim) *dp++ = c;
|
||||
/* If it precedes a ., scale must be adjusted */
|
||||
if (!dotseen) scale++;
|
||||
}
|
||||
if (sp == save) {
|
||||
if (ptr) *ptr = str;
|
||||
errno = EDOM; /* what should this be? */
|
||||
return ZERO;
|
||||
}
|
||||
int sign, scale, dotseen;
|
||||
int esign, expt;
|
||||
char *save;
|
||||
register char *sp, *dp;
|
||||
register int c;
|
||||
char *buforg, *buflim;
|
||||
char buffer[64]; /* 45-digit significant + */
|
||||
/* 13-digit exponent */
|
||||
sp = str;
|
||||
while (*sp == ' ') sp++;
|
||||
sign = 1;
|
||||
if (*sp == '-') sign -= 2, sp++;
|
||||
dotseen = 0, scale = 0;
|
||||
dp = buffer;
|
||||
*dp++ = '0'; *dp++ = '.';
|
||||
buforg = dp, buflim = buffer+48;
|
||||
for (save = sp; (c = *sp); sp++)
|
||||
if (c == '.') {
|
||||
if (dotseen) break;
|
||||
dotseen++;
|
||||
} else
|
||||
if ((unsigned)(c-'0') > (unsigned)('9'-'0')) {
|
||||
break;
|
||||
} else
|
||||
if (c == '0') {
|
||||
if (dp != buforg) {
|
||||
/* This is not the first digit, so we want to keep it */
|
||||
if (dp < buflim) *dp++ = c;
|
||||
if (!dotseen) scale++;
|
||||
} else {
|
||||
/* No non-zero digits seen yet */
|
||||
/* If a . has been seen, scale must be adjusted */
|
||||
if (dotseen) scale--;
|
||||
}
|
||||
} else {
|
||||
/* This is a nonzero digit, so we want to keep it */
|
||||
if (dp < buflim) *dp++ = c;
|
||||
/* If it precedes a ., scale must be adjusted */
|
||||
if (!dotseen) scale++;
|
||||
}
|
||||
if (sp == save) {
|
||||
if (ptr) *ptr = str;
|
||||
errno = EDOM; /* what should this be? */
|
||||
return ZERO;
|
||||
}
|
||||
|
||||
while (dp > buforg && dp[-1] == '0') --dp;
|
||||
if (dp == buforg) *dp++ = '0';
|
||||
*dp = '\0';
|
||||
/* Now the contents of buffer are
|
||||
+--+--------+-+--------+
|
||||
|0.|fraction|\|leftover|
|
||||
+--+--------+-+--------+
|
||||
^dp points here
|
||||
where fraction begins with 0 iff it is "0", and has at most
|
||||
45 digits in it, and leftover is at least 16 characters.
|
||||
*/
|
||||
save = sp, expt = 0, esign = 1;
|
||||
do {
|
||||
c = *sp++;
|
||||
if (c != 'e' && c != 'E') break;
|
||||
c = *sp++;
|
||||
if (c == '-') esign -= 2, c = *sp++; else
|
||||
if (c == '+' /* || c == ' ' */ ) c = *sp++;
|
||||
if ((unsigned)(c-'0') > (unsigned)('9'-'0')) break;
|
||||
while (c == '0') c = *sp++;
|
||||
for (; (unsigned)(c-'0') <= (unsigned)('9'-'0'); c = *sp++)
|
||||
expt = expt*10 + c-'0';
|
||||
if (esign < 0) expt = -expt;
|
||||
save = sp-1;
|
||||
} while (0);
|
||||
if (ptr) *ptr = save;
|
||||
expt += scale;
|
||||
/* Now the number is sign*0.fraction*10**expt */
|
||||
errno = ERANGE;
|
||||
if (expt > MDMAXEXPT) {
|
||||
return HUGE*sign;
|
||||
} else
|
||||
if (expt == MDMAXEXPT) {
|
||||
if (strcmp(buforg, MDMAXFRAC) > 0) return HUGE*sign;
|
||||
} else
|
||||
if (expt < MDMINEXPT) {
|
||||
return ZERO*sign;
|
||||
} else
|
||||
if (expt == MDMINEXPT) {
|
||||
if (strcmp(buforg, MDMINFRAC) < 0) return ZERO*sign;
|
||||
}
|
||||
/* We have now established that the number can be */
|
||||
/* represented without overflow or underflow */
|
||||
(void) sprintf(dp, "E%d", expt);
|
||||
errno = 0;
|
||||
return atof(buffer)*sign;
|
||||
while (dp > buforg && dp[-1] == '0') --dp;
|
||||
if (dp == buforg) *dp++ = '0';
|
||||
*dp = '\0';
|
||||
/* Now the contents of buffer are
|
||||
+--+--------+-+--------+
|
||||
|0.|fraction|\|leftover|
|
||||
+--+--------+-+--------+
|
||||
^dp points here
|
||||
where fraction begins with 0 iff it is "0", and has at most
|
||||
45 digits in it, and leftover is at least 16 characters.
|
||||
*/
|
||||
save = sp, expt = 0, esign = 1;
|
||||
do {
|
||||
c = *sp++;
|
||||
if (c != 'e' && c != 'E') break;
|
||||
c = *sp++;
|
||||
if (c == '-') esign -= 2, c = *sp++; else
|
||||
if (c == '+' /* || c == ' ' */ ) c = *sp++;
|
||||
if ((unsigned)(c-'0') > (unsigned)('9'-'0')) break;
|
||||
while (c == '0') c = *sp++;
|
||||
for (; (unsigned)(c-'0') <= (unsigned)('9'-'0'); c = *sp++)
|
||||
expt = expt*10 + c-'0';
|
||||
if (esign < 0) expt = -expt;
|
||||
save = sp-1;
|
||||
} while (0);
|
||||
if (ptr) *ptr = save;
|
||||
expt += scale;
|
||||
/* Now the number is sign*0.fraction*10**expt */
|
||||
errno = ERANGE;
|
||||
if (expt > MDMAXEXPT) {
|
||||
return HUGE*sign;
|
||||
} else
|
||||
if (expt == MDMAXEXPT) {
|
||||
if (strcmp(buforg, MDMAXFRAC) > 0) return HUGE*sign;
|
||||
} else
|
||||
if (expt < MDMINEXPT) {
|
||||
return ZERO*sign;
|
||||
} else
|
||||
if (expt == MDMINEXPT) {
|
||||
if (strcmp(buforg, MDMINFRAC) < 0) return ZERO*sign;
|
||||
}
|
||||
/* We have now established that the number can be */
|
||||
/* represented without overflow or underflow */
|
||||
(void) sprintf(dp, "E%d", expt);
|
||||
errno = 0;
|
||||
return atof(buffer)*sign;
|
||||
}
|
||||
|
|
|
@ -8,356 +8,356 @@
|
|||
static PyObject *
|
||||
listmembers(struct memberlist *mlist)
|
||||
{
|
||||
int i, n;
|
||||
PyObject *v;
|
||||
for (n = 0; mlist[n].name != NULL; n++)
|
||||
;
|
||||
v = PyList_New(n);
|
||||
if (v != NULL) {
|
||||
for (i = 0; i < n; i++)
|
||||
PyList_SetItem(v, i,
|
||||
PyString_FromString(mlist[i].name));
|
||||
if (PyErr_Occurred()) {
|
||||
Py_DECREF(v);
|
||||
v = NULL;
|
||||
}
|
||||
else {
|
||||
PyList_Sort(v);
|
||||
}
|
||||
}
|
||||
return v;
|
||||
int i, n;
|
||||
PyObject *v;
|
||||
for (n = 0; mlist[n].name != NULL; n++)
|
||||
;
|
||||
v = PyList_New(n);
|
||||
if (v != NULL) {
|
||||
for (i = 0; i < n; i++)
|
||||
PyList_SetItem(v, i,
|
||||
PyString_FromString(mlist[i].name));
|
||||
if (PyErr_Occurred()) {
|
||||
Py_DECREF(v);
|
||||
v = NULL;
|
||||
}
|
||||
else {
|
||||
PyList_Sort(v);
|
||||
}
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
PyObject *
|
||||
PyMember_Get(const char *addr, struct memberlist *mlist, const char *name)
|
||||
{
|
||||
struct memberlist *l;
|
||||
struct memberlist *l;
|
||||
|
||||
if (strcmp(name, "__members__") == 0)
|
||||
return listmembers(mlist);
|
||||
for (l = mlist; l->name != NULL; l++) {
|
||||
if (strcmp(l->name, name) == 0) {
|
||||
PyMemberDef copy;
|
||||
copy.name = l->name;
|
||||
copy.type = l->type;
|
||||
copy.offset = l->offset;
|
||||
copy.flags = l->flags;
|
||||
copy.doc = NULL;
|
||||
return PyMember_GetOne(addr, ©);
|
||||
}
|
||||
}
|
||||
PyErr_SetString(PyExc_AttributeError, name);
|
||||
return NULL;
|
||||
if (strcmp(name, "__members__") == 0)
|
||||
return listmembers(mlist);
|
||||
for (l = mlist; l->name != NULL; l++) {
|
||||
if (strcmp(l->name, name) == 0) {
|
||||
PyMemberDef copy;
|
||||
copy.name = l->name;
|
||||
copy.type = l->type;
|
||||
copy.offset = l->offset;
|
||||
copy.flags = l->flags;
|
||||
copy.doc = NULL;
|
||||
return PyMember_GetOne(addr, ©);
|
||||
}
|
||||
}
|
||||
PyErr_SetString(PyExc_AttributeError, name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PyObject *
|
||||
PyMember_GetOne(const char *addr, PyMemberDef *l)
|
||||
{
|
||||
PyObject *v;
|
||||
if ((l->flags & READ_RESTRICTED) &&
|
||||
PyEval_GetRestricted()) {
|
||||
PyErr_SetString(PyExc_RuntimeError, "restricted attribute");
|
||||
return NULL;
|
||||
}
|
||||
addr += l->offset;
|
||||
switch (l->type) {
|
||||
case T_BOOL:
|
||||
v = PyBool_FromLong(*(char*)addr);
|
||||
break;
|
||||
case T_BYTE:
|
||||
v = PyInt_FromLong(*(char*)addr);
|
||||
break;
|
||||
case T_UBYTE:
|
||||
v = PyLong_FromUnsignedLong(*(unsigned char*)addr);
|
||||
break;
|
||||
case T_SHORT:
|
||||
v = PyInt_FromLong(*(short*)addr);
|
||||
break;
|
||||
case T_USHORT:
|
||||
v = PyLong_FromUnsignedLong(*(unsigned short*)addr);
|
||||
break;
|
||||
case T_INT:
|
||||
v = PyInt_FromLong(*(int*)addr);
|
||||
break;
|
||||
case T_UINT:
|
||||
v = PyLong_FromUnsignedLong(*(unsigned int*)addr);
|
||||
break;
|
||||
case T_LONG:
|
||||
v = PyInt_FromLong(*(long*)addr);
|
||||
break;
|
||||
case T_ULONG:
|
||||
v = PyLong_FromUnsignedLong(*(unsigned long*)addr);
|
||||
break;
|
||||
case T_PYSSIZET:
|
||||
v = PyInt_FromSsize_t(*(Py_ssize_t*)addr);
|
||||
break;
|
||||
case T_FLOAT:
|
||||
v = PyFloat_FromDouble((double)*(float*)addr);
|
||||
break;
|
||||
case T_DOUBLE:
|
||||
v = PyFloat_FromDouble(*(double*)addr);
|
||||
break;
|
||||
case T_STRING:
|
||||
if (*(char**)addr == NULL) {
|
||||
Py_INCREF(Py_None);
|
||||
v = Py_None;
|
||||
}
|
||||
else
|
||||
v = PyString_FromString(*(char**)addr);
|
||||
break;
|
||||
case T_STRING_INPLACE:
|
||||
v = PyString_FromString((char*)addr);
|
||||
break;
|
||||
case T_CHAR:
|
||||
v = PyString_FromStringAndSize((char*)addr, 1);
|
||||
break;
|
||||
case T_OBJECT:
|
||||
v = *(PyObject **)addr;
|
||||
if (v == NULL)
|
||||
v = Py_None;
|
||||
Py_INCREF(v);
|
||||
break;
|
||||
case T_OBJECT_EX:
|
||||
v = *(PyObject **)addr;
|
||||
if (v == NULL)
|
||||
PyErr_SetString(PyExc_AttributeError, l->name);
|
||||
Py_XINCREF(v);
|
||||
break;
|
||||
PyObject *v;
|
||||
if ((l->flags & READ_RESTRICTED) &&
|
||||
PyEval_GetRestricted()) {
|
||||
PyErr_SetString(PyExc_RuntimeError, "restricted attribute");
|
||||
return NULL;
|
||||
}
|
||||
addr += l->offset;
|
||||
switch (l->type) {
|
||||
case T_BOOL:
|
||||
v = PyBool_FromLong(*(char*)addr);
|
||||
break;
|
||||
case T_BYTE:
|
||||
v = PyInt_FromLong(*(char*)addr);
|
||||
break;
|
||||
case T_UBYTE:
|
||||
v = PyLong_FromUnsignedLong(*(unsigned char*)addr);
|
||||
break;
|
||||
case T_SHORT:
|
||||
v = PyInt_FromLong(*(short*)addr);
|
||||
break;
|
||||
case T_USHORT:
|
||||
v = PyLong_FromUnsignedLong(*(unsigned short*)addr);
|
||||
break;
|
||||
case T_INT:
|
||||
v = PyInt_FromLong(*(int*)addr);
|
||||
break;
|
||||
case T_UINT:
|
||||
v = PyLong_FromUnsignedLong(*(unsigned int*)addr);
|
||||
break;
|
||||
case T_LONG:
|
||||
v = PyInt_FromLong(*(long*)addr);
|
||||
break;
|
||||
case T_ULONG:
|
||||
v = PyLong_FromUnsignedLong(*(unsigned long*)addr);
|
||||
break;
|
||||
case T_PYSSIZET:
|
||||
v = PyInt_FromSsize_t(*(Py_ssize_t*)addr);
|
||||
break;
|
||||
case T_FLOAT:
|
||||
v = PyFloat_FromDouble((double)*(float*)addr);
|
||||
break;
|
||||
case T_DOUBLE:
|
||||
v = PyFloat_FromDouble(*(double*)addr);
|
||||
break;
|
||||
case T_STRING:
|
||||
if (*(char**)addr == NULL) {
|
||||
Py_INCREF(Py_None);
|
||||
v = Py_None;
|
||||
}
|
||||
else
|
||||
v = PyString_FromString(*(char**)addr);
|
||||
break;
|
||||
case T_STRING_INPLACE:
|
||||
v = PyString_FromString((char*)addr);
|
||||
break;
|
||||
case T_CHAR:
|
||||
v = PyString_FromStringAndSize((char*)addr, 1);
|
||||
break;
|
||||
case T_OBJECT:
|
||||
v = *(PyObject **)addr;
|
||||
if (v == NULL)
|
||||
v = Py_None;
|
||||
Py_INCREF(v);
|
||||
break;
|
||||
case T_OBJECT_EX:
|
||||
v = *(PyObject **)addr;
|
||||
if (v == NULL)
|
||||
PyErr_SetString(PyExc_AttributeError, l->name);
|
||||
Py_XINCREF(v);
|
||||
break;
|
||||
#ifdef HAVE_LONG_LONG
|
||||
case T_LONGLONG:
|
||||
v = PyLong_FromLongLong(*(PY_LONG_LONG *)addr);
|
||||
break;
|
||||
case T_ULONGLONG:
|
||||
v = PyLong_FromUnsignedLongLong(*(unsigned PY_LONG_LONG *)addr);
|
||||
break;
|
||||
case T_LONGLONG:
|
||||
v = PyLong_FromLongLong(*(PY_LONG_LONG *)addr);
|
||||
break;
|
||||
case T_ULONGLONG:
|
||||
v = PyLong_FromUnsignedLongLong(*(unsigned PY_LONG_LONG *)addr);
|
||||
break;
|
||||
#endif /* HAVE_LONG_LONG */
|
||||
default:
|
||||
PyErr_SetString(PyExc_SystemError, "bad memberdescr type");
|
||||
v = NULL;
|
||||
}
|
||||
return v;
|
||||
default:
|
||||
PyErr_SetString(PyExc_SystemError, "bad memberdescr type");
|
||||
v = NULL;
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
int
|
||||
PyMember_Set(char *addr, struct memberlist *mlist, const char *name, PyObject *v)
|
||||
{
|
||||
struct memberlist *l;
|
||||
struct memberlist *l;
|
||||
|
||||
for (l = mlist; l->name != NULL; l++) {
|
||||
if (strcmp(l->name, name) == 0) {
|
||||
PyMemberDef copy;
|
||||
copy.name = l->name;
|
||||
copy.type = l->type;
|
||||
copy.offset = l->offset;
|
||||
copy.flags = l->flags;
|
||||
copy.doc = NULL;
|
||||
return PyMember_SetOne(addr, ©, v);
|
||||
}
|
||||
}
|
||||
for (l = mlist; l->name != NULL; l++) {
|
||||
if (strcmp(l->name, name) == 0) {
|
||||
PyMemberDef copy;
|
||||
copy.name = l->name;
|
||||
copy.type = l->type;
|
||||
copy.offset = l->offset;
|
||||
copy.flags = l->flags;
|
||||
copy.doc = NULL;
|
||||
return PyMember_SetOne(addr, ©, v);
|
||||
}
|
||||
}
|
||||
|
||||
PyErr_SetString(PyExc_AttributeError, name);
|
||||
return -1;
|
||||
PyErr_SetString(PyExc_AttributeError, name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
#define WARN(msg) \
|
||||
do { \
|
||||
if (PyErr_Warn(PyExc_RuntimeWarning, msg) < 0) \
|
||||
return -1; \
|
||||
#define WARN(msg) \
|
||||
do { \
|
||||
if (PyErr_Warn(PyExc_RuntimeWarning, msg) < 0) \
|
||||
return -1; \
|
||||
} while (0)
|
||||
|
||||
int
|
||||
PyMember_SetOne(char *addr, PyMemberDef *l, PyObject *v)
|
||||
{
|
||||
PyObject *oldv;
|
||||
PyObject *oldv;
|
||||
|
||||
addr += l->offset;
|
||||
addr += l->offset;
|
||||
|
||||
if ((l->flags & READONLY))
|
||||
{
|
||||
PyErr_SetString(PyExc_TypeError, "readonly attribute");
|
||||
return -1;
|
||||
}
|
||||
if ((l->flags & PY_WRITE_RESTRICTED) && PyEval_GetRestricted()) {
|
||||
PyErr_SetString(PyExc_RuntimeError, "restricted attribute");
|
||||
return -1;
|
||||
}
|
||||
if (v == NULL) {
|
||||
if (l->type == T_OBJECT_EX) {
|
||||
/* Check if the attribute is set. */
|
||||
if (*(PyObject **)addr == NULL) {
|
||||
PyErr_SetString(PyExc_AttributeError, l->name);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else if (l->type != T_OBJECT) {
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"can't delete numeric/char attribute");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
switch (l->type) {
|
||||
case T_BOOL:{
|
||||
if (!PyBool_Check(v)) {
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"attribute value type must be bool");
|
||||
return -1;
|
||||
}
|
||||
if (v == Py_True)
|
||||
*(char*)addr = (char) 1;
|
||||
else
|
||||
*(char*)addr = (char) 0;
|
||||
break;
|
||||
}
|
||||
case T_BYTE:{
|
||||
long long_val = PyInt_AsLong(v);
|
||||
if ((long_val == -1) && PyErr_Occurred())
|
||||
return -1;
|
||||
*(char*)addr = (char)long_val;
|
||||
/* XXX: For compatibility, only warn about truncations
|
||||
for now. */
|
||||
if ((long_val > CHAR_MAX) || (long_val < CHAR_MIN))
|
||||
WARN("Truncation of value to char");
|
||||
break;
|
||||
}
|
||||
case T_UBYTE:{
|
||||
long long_val = PyInt_AsLong(v);
|
||||
if ((long_val == -1) && PyErr_Occurred())
|
||||
return -1;
|
||||
*(unsigned char*)addr = (unsigned char)long_val;
|
||||
if ((long_val > UCHAR_MAX) || (long_val < 0))
|
||||
WARN("Truncation of value to unsigned char");
|
||||
break;
|
||||
}
|
||||
case T_SHORT:{
|
||||
long long_val = PyInt_AsLong(v);
|
||||
if ((long_val == -1) && PyErr_Occurred())
|
||||
return -1;
|
||||
*(short*)addr = (short)long_val;
|
||||
if ((long_val > SHRT_MAX) || (long_val < SHRT_MIN))
|
||||
WARN("Truncation of value to short");
|
||||
break;
|
||||
}
|
||||
case T_USHORT:{
|
||||
long long_val = PyInt_AsLong(v);
|
||||
if ((long_val == -1) && PyErr_Occurred())
|
||||
return -1;
|
||||
*(unsigned short*)addr = (unsigned short)long_val;
|
||||
if ((long_val > USHRT_MAX) || (long_val < 0))
|
||||
WARN("Truncation of value to unsigned short");
|
||||
break;
|
||||
}
|
||||
case T_INT:{
|
||||
long long_val = PyInt_AsLong(v);
|
||||
if ((long_val == -1) && PyErr_Occurred())
|
||||
return -1;
|
||||
*(int *)addr = (int)long_val;
|
||||
if ((long_val > INT_MAX) || (long_val < INT_MIN))
|
||||
WARN("Truncation of value to int");
|
||||
break;
|
||||
}
|
||||
case T_UINT:{
|
||||
unsigned long ulong_val = PyLong_AsUnsignedLong(v);
|
||||
if ((ulong_val == (unsigned long)-1) && PyErr_Occurred()) {
|
||||
/* XXX: For compatibility, accept negative int values
|
||||
as well. */
|
||||
PyErr_Clear();
|
||||
ulong_val = PyLong_AsLong(v);
|
||||
if ((ulong_val == (unsigned long)-1) &&
|
||||
PyErr_Occurred())
|
||||
return -1;
|
||||
*(unsigned int *)addr = (unsigned int)ulong_val;
|
||||
WARN("Writing negative value into unsigned field");
|
||||
} else
|
||||
*(unsigned int *)addr = (unsigned int)ulong_val;
|
||||
if (ulong_val > UINT_MAX)
|
||||
WARN("Truncation of value to unsigned int");
|
||||
break;
|
||||
}
|
||||
case T_LONG:{
|
||||
*(long*)addr = PyLong_AsLong(v);
|
||||
if ((*(long*)addr == -1) && PyErr_Occurred())
|
||||
return -1;
|
||||
break;
|
||||
}
|
||||
case T_ULONG:{
|
||||
*(unsigned long*)addr = PyLong_AsUnsignedLong(v);
|
||||
if ((*(unsigned long*)addr == (unsigned long)-1)
|
||||
&& PyErr_Occurred()) {
|
||||
/* XXX: For compatibility, accept negative int values
|
||||
as well. */
|
||||
PyErr_Clear();
|
||||
*(unsigned long*)addr = PyLong_AsLong(v);
|
||||
if ((*(unsigned long*)addr == (unsigned long)-1)
|
||||
&& PyErr_Occurred())
|
||||
return -1;
|
||||
WARN("Writing negative value into unsigned field");
|
||||
}
|
||||
break;
|
||||
}
|
||||
case T_PYSSIZET:{
|
||||
*(Py_ssize_t*)addr = PyInt_AsSsize_t(v);
|
||||
if ((*(Py_ssize_t*)addr == (Py_ssize_t)-1)
|
||||
&& PyErr_Occurred())
|
||||
return -1;
|
||||
break;
|
||||
}
|
||||
case T_FLOAT:{
|
||||
double double_val = PyFloat_AsDouble(v);
|
||||
if ((double_val == -1) && PyErr_Occurred())
|
||||
return -1;
|
||||
*(float*)addr = (float)double_val;
|
||||
break;
|
||||
}
|
||||
case T_DOUBLE:
|
||||
*(double*)addr = PyFloat_AsDouble(v);
|
||||
if ((*(double*)addr == -1) && PyErr_Occurred())
|
||||
return -1;
|
||||
break;
|
||||
case T_OBJECT:
|
||||
case T_OBJECT_EX:
|
||||
Py_XINCREF(v);
|
||||
oldv = *(PyObject **)addr;
|
||||
*(PyObject **)addr = v;
|
||||
Py_XDECREF(oldv);
|
||||
break;
|
||||
case T_CHAR:
|
||||
if (PyString_Check(v) && PyString_Size(v) == 1) {
|
||||
*(char*)addr = PyString_AsString(v)[0];
|
||||
}
|
||||
else {
|
||||
PyErr_BadArgument();
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
case T_STRING:
|
||||
case T_STRING_INPLACE:
|
||||
PyErr_SetString(PyExc_TypeError, "readonly attribute");
|
||||
return -1;
|
||||
if ((l->flags & READONLY))
|
||||
{
|
||||
PyErr_SetString(PyExc_TypeError, "readonly attribute");
|
||||
return -1;
|
||||
}
|
||||
if ((l->flags & PY_WRITE_RESTRICTED) && PyEval_GetRestricted()) {
|
||||
PyErr_SetString(PyExc_RuntimeError, "restricted attribute");
|
||||
return -1;
|
||||
}
|
||||
if (v == NULL) {
|
||||
if (l->type == T_OBJECT_EX) {
|
||||
/* Check if the attribute is set. */
|
||||
if (*(PyObject **)addr == NULL) {
|
||||
PyErr_SetString(PyExc_AttributeError, l->name);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else if (l->type != T_OBJECT) {
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"can't delete numeric/char attribute");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
switch (l->type) {
|
||||
case T_BOOL:{
|
||||
if (!PyBool_Check(v)) {
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"attribute value type must be bool");
|
||||
return -1;
|
||||
}
|
||||
if (v == Py_True)
|
||||
*(char*)addr = (char) 1;
|
||||
else
|
||||
*(char*)addr = (char) 0;
|
||||
break;
|
||||
}
|
||||
case T_BYTE:{
|
||||
long long_val = PyInt_AsLong(v);
|
||||
if ((long_val == -1) && PyErr_Occurred())
|
||||
return -1;
|
||||
*(char*)addr = (char)long_val;
|
||||
/* XXX: For compatibility, only warn about truncations
|
||||
for now. */
|
||||
if ((long_val > CHAR_MAX) || (long_val < CHAR_MIN))
|
||||
WARN("Truncation of value to char");
|
||||
break;
|
||||
}
|
||||
case T_UBYTE:{
|
||||
long long_val = PyInt_AsLong(v);
|
||||
if ((long_val == -1) && PyErr_Occurred())
|
||||
return -1;
|
||||
*(unsigned char*)addr = (unsigned char)long_val;
|
||||
if ((long_val > UCHAR_MAX) || (long_val < 0))
|
||||
WARN("Truncation of value to unsigned char");
|
||||
break;
|
||||
}
|
||||
case T_SHORT:{
|
||||
long long_val = PyInt_AsLong(v);
|
||||
if ((long_val == -1) && PyErr_Occurred())
|
||||
return -1;
|
||||
*(short*)addr = (short)long_val;
|
||||
if ((long_val > SHRT_MAX) || (long_val < SHRT_MIN))
|
||||
WARN("Truncation of value to short");
|
||||
break;
|
||||
}
|
||||
case T_USHORT:{
|
||||
long long_val = PyInt_AsLong(v);
|
||||
if ((long_val == -1) && PyErr_Occurred())
|
||||
return -1;
|
||||
*(unsigned short*)addr = (unsigned short)long_val;
|
||||
if ((long_val > USHRT_MAX) || (long_val < 0))
|
||||
WARN("Truncation of value to unsigned short");
|
||||
break;
|
||||
}
|
||||
case T_INT:{
|
||||
long long_val = PyInt_AsLong(v);
|
||||
if ((long_val == -1) && PyErr_Occurred())
|
||||
return -1;
|
||||
*(int *)addr = (int)long_val;
|
||||
if ((long_val > INT_MAX) || (long_val < INT_MIN))
|
||||
WARN("Truncation of value to int");
|
||||
break;
|
||||
}
|
||||
case T_UINT:{
|
||||
unsigned long ulong_val = PyLong_AsUnsignedLong(v);
|
||||
if ((ulong_val == (unsigned long)-1) && PyErr_Occurred()) {
|
||||
/* XXX: For compatibility, accept negative int values
|
||||
as well. */
|
||||
PyErr_Clear();
|
||||
ulong_val = PyLong_AsLong(v);
|
||||
if ((ulong_val == (unsigned long)-1) &&
|
||||
PyErr_Occurred())
|
||||
return -1;
|
||||
*(unsigned int *)addr = (unsigned int)ulong_val;
|
||||
WARN("Writing negative value into unsigned field");
|
||||
} else
|
||||
*(unsigned int *)addr = (unsigned int)ulong_val;
|
||||
if (ulong_val > UINT_MAX)
|
||||
WARN("Truncation of value to unsigned int");
|
||||
break;
|
||||
}
|
||||
case T_LONG:{
|
||||
*(long*)addr = PyLong_AsLong(v);
|
||||
if ((*(long*)addr == -1) && PyErr_Occurred())
|
||||
return -1;
|
||||
break;
|
||||
}
|
||||
case T_ULONG:{
|
||||
*(unsigned long*)addr = PyLong_AsUnsignedLong(v);
|
||||
if ((*(unsigned long*)addr == (unsigned long)-1)
|
||||
&& PyErr_Occurred()) {
|
||||
/* XXX: For compatibility, accept negative int values
|
||||
as well. */
|
||||
PyErr_Clear();
|
||||
*(unsigned long*)addr = PyLong_AsLong(v);
|
||||
if ((*(unsigned long*)addr == (unsigned long)-1)
|
||||
&& PyErr_Occurred())
|
||||
return -1;
|
||||
WARN("Writing negative value into unsigned field");
|
||||
}
|
||||
break;
|
||||
}
|
||||
case T_PYSSIZET:{
|
||||
*(Py_ssize_t*)addr = PyInt_AsSsize_t(v);
|
||||
if ((*(Py_ssize_t*)addr == (Py_ssize_t)-1)
|
||||
&& PyErr_Occurred())
|
||||
return -1;
|
||||
break;
|
||||
}
|
||||
case T_FLOAT:{
|
||||
double double_val = PyFloat_AsDouble(v);
|
||||
if ((double_val == -1) && PyErr_Occurred())
|
||||
return -1;
|
||||
*(float*)addr = (float)double_val;
|
||||
break;
|
||||
}
|
||||
case T_DOUBLE:
|
||||
*(double*)addr = PyFloat_AsDouble(v);
|
||||
if ((*(double*)addr == -1) && PyErr_Occurred())
|
||||
return -1;
|
||||
break;
|
||||
case T_OBJECT:
|
||||
case T_OBJECT_EX:
|
||||
Py_XINCREF(v);
|
||||
oldv = *(PyObject **)addr;
|
||||
*(PyObject **)addr = v;
|
||||
Py_XDECREF(oldv);
|
||||
break;
|
||||
case T_CHAR:
|
||||
if (PyString_Check(v) && PyString_Size(v) == 1) {
|
||||
*(char*)addr = PyString_AsString(v)[0];
|
||||
}
|
||||
else {
|
||||
PyErr_BadArgument();
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
case T_STRING:
|
||||
case T_STRING_INPLACE:
|
||||
PyErr_SetString(PyExc_TypeError, "readonly attribute");
|
||||
return -1;
|
||||
#ifdef HAVE_LONG_LONG
|
||||
case T_LONGLONG:{
|
||||
PY_LONG_LONG value;
|
||||
*(PY_LONG_LONG*)addr = value = PyLong_AsLongLong(v);
|
||||
if ((value == -1) && PyErr_Occurred())
|
||||
return -1;
|
||||
break;
|
||||
}
|
||||
case T_ULONGLONG:{
|
||||
unsigned PY_LONG_LONG value;
|
||||
/* ??? PyLong_AsLongLong accepts an int, but PyLong_AsUnsignedLongLong
|
||||
doesn't ??? */
|
||||
if (PyLong_Check(v))
|
||||
*(unsigned PY_LONG_LONG*)addr = value = PyLong_AsUnsignedLongLong(v);
|
||||
else
|
||||
*(unsigned PY_LONG_LONG*)addr = value = PyInt_AsLong(v);
|
||||
if ((value == (unsigned PY_LONG_LONG)-1) && PyErr_Occurred())
|
||||
return -1;
|
||||
break;
|
||||
}
|
||||
case T_LONGLONG:{
|
||||
PY_LONG_LONG value;
|
||||
*(PY_LONG_LONG*)addr = value = PyLong_AsLongLong(v);
|
||||
if ((value == -1) && PyErr_Occurred())
|
||||
return -1;
|
||||
break;
|
||||
}
|
||||
case T_ULONGLONG:{
|
||||
unsigned PY_LONG_LONG value;
|
||||
/* ??? PyLong_AsLongLong accepts an int, but PyLong_AsUnsignedLongLong
|
||||
doesn't ??? */
|
||||
if (PyLong_Check(v))
|
||||
*(unsigned PY_LONG_LONG*)addr = value = PyLong_AsUnsignedLongLong(v);
|
||||
else
|
||||
*(unsigned PY_LONG_LONG*)addr = value = PyInt_AsLong(v);
|
||||
if ((value == (unsigned PY_LONG_LONG)-1) && PyErr_Occurred())
|
||||
return -1;
|
||||
break;
|
||||
}
|
||||
#endif /* HAVE_LONG_LONG */
|
||||
default:
|
||||
PyErr_Format(PyExc_SystemError,
|
||||
"bad memberdescr type for %s", l->name);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
default:
|
||||
PyErr_Format(PyExc_SystemError,
|
||||
"bad memberdescr type for %s", l->name);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
2354
Python/symtable.c
2354
Python/symtable.c
File diff suppressed because it is too large
Load diff
1850
Python/sysmodule.c
1850
Python/sysmodule.c
File diff suppressed because it is too large
Load diff
250
Python/thread.c
250
Python/thread.c
|
@ -46,7 +46,7 @@
|
|||
#endif
|
||||
|
||||
/* Check if we're running on HP-UX and _SC_THREADS is defined. If so, then
|
||||
enough of the Posix threads package is implimented to support python
|
||||
enough of the Posix threads package is implimented to support python
|
||||
threads.
|
||||
|
||||
This is valid for HP-UX 11.23 running on an ia64 system. If needed, add
|
||||
|
@ -64,8 +64,8 @@
|
|||
|
||||
#ifdef Py_DEBUG
|
||||
static int thread_debug = 0;
|
||||
#define dprintf(args) (void)((thread_debug & 1) && printf args)
|
||||
#define d2printf(args) ((thread_debug & 8) && printf args)
|
||||
#define dprintf(args) (void)((thread_debug & 1) && printf args)
|
||||
#define d2printf(args) ((thread_debug & 8) && printf args)
|
||||
#else
|
||||
#define dprintf(args)
|
||||
#define d2printf(args)
|
||||
|
@ -79,20 +79,20 @@ void
|
|||
PyThread_init_thread(void)
|
||||
{
|
||||
#ifdef Py_DEBUG
|
||||
char *p = Py_GETENV("PYTHONTHREADDEBUG");
|
||||
char *p = Py_GETENV("PYTHONTHREADDEBUG");
|
||||
|
||||
if (p) {
|
||||
if (*p)
|
||||
thread_debug = atoi(p);
|
||||
else
|
||||
thread_debug = 1;
|
||||
}
|
||||
if (p) {
|
||||
if (*p)
|
||||
thread_debug = atoi(p);
|
||||
else
|
||||
thread_debug = 1;
|
||||
}
|
||||
#endif /* Py_DEBUG */
|
||||
if (initialized)
|
||||
return;
|
||||
initialized = 1;
|
||||
dprintf(("PyThread_init_thread called\n"));
|
||||
PyThread__init_thread();
|
||||
if (initialized)
|
||||
return;
|
||||
initialized = 1;
|
||||
dprintf(("PyThread_init_thread called\n"));
|
||||
PyThread__init_thread();
|
||||
}
|
||||
|
||||
/* Support for runtime thread stack size tuning.
|
||||
|
@ -155,21 +155,21 @@ static size_t _pythread_stacksize = 0;
|
|||
size_t
|
||||
PyThread_get_stacksize(void)
|
||||
{
|
||||
return _pythread_stacksize;
|
||||
return _pythread_stacksize;
|
||||
}
|
||||
|
||||
/* Only platforms defining a THREAD_SET_STACKSIZE() macro
|
||||
in thread_<platform>.h support changing the stack size.
|
||||
Return 0 if stack size is valid,
|
||||
-1 if stack size value is invalid,
|
||||
-2 if setting stack size is not supported. */
|
||||
-1 if stack size value is invalid,
|
||||
-2 if setting stack size is not supported. */
|
||||
int
|
||||
PyThread_set_stacksize(size_t size)
|
||||
{
|
||||
#if defined(THREAD_SET_STACKSIZE)
|
||||
return THREAD_SET_STACKSIZE(size);
|
||||
return THREAD_SET_STACKSIZE(size);
|
||||
#else
|
||||
return -2;
|
||||
return -2;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -221,15 +221,15 @@ that calls to PyThread_create_key() are serialized externally.
|
|||
* to enforce exclusion internally.
|
||||
*/
|
||||
struct key {
|
||||
/* Next record in the list, or NULL if this is the last record. */
|
||||
struct key *next;
|
||||
/* Next record in the list, or NULL if this is the last record. */
|
||||
struct key *next;
|
||||
|
||||
/* The thread id, according to PyThread_get_thread_ident(). */
|
||||
long id;
|
||||
/* The thread id, according to PyThread_get_thread_ident(). */
|
||||
long id;
|
||||
|
||||
/* The key and its associated value. */
|
||||
int key;
|
||||
void *value;
|
||||
/* The key and its associated value. */
|
||||
int key;
|
||||
void *value;
|
||||
};
|
||||
|
||||
static struct key *keyhead = NULL;
|
||||
|
@ -260,41 +260,41 @@ static int nkeys = 0; /* PyThread_create_key() hands out nkeys+1 next */
|
|||
static struct key *
|
||||
find_key(int key, void *value)
|
||||
{
|
||||
struct key *p, *prev_p;
|
||||
long id = PyThread_get_thread_ident();
|
||||
struct key *p, *prev_p;
|
||||
long id = PyThread_get_thread_ident();
|
||||
|
||||
if (!keymutex)
|
||||
return NULL;
|
||||
PyThread_acquire_lock(keymutex, 1);
|
||||
prev_p = NULL;
|
||||
for (p = keyhead; p != NULL; p = p->next) {
|
||||
if (p->id == id && p->key == key)
|
||||
goto Done;
|
||||
/* Sanity check. These states should never happen but if
|
||||
* they do we must abort. Otherwise we'll end up spinning in
|
||||
* in a tight loop with the lock held. A similar check is done
|
||||
* in pystate.c tstate_delete_common(). */
|
||||
if (p == prev_p)
|
||||
Py_FatalError("tls find_key: small circular list(!)");
|
||||
prev_p = p;
|
||||
if (p->next == keyhead)
|
||||
Py_FatalError("tls find_key: circular list(!)");
|
||||
}
|
||||
if (value == NULL) {
|
||||
assert(p == NULL);
|
||||
goto Done;
|
||||
}
|
||||
p = (struct key *)malloc(sizeof(struct key));
|
||||
if (p != NULL) {
|
||||
p->id = id;
|
||||
p->key = key;
|
||||
p->value = value;
|
||||
p->next = keyhead;
|
||||
keyhead = p;
|
||||
}
|
||||
if (!keymutex)
|
||||
return NULL;
|
||||
PyThread_acquire_lock(keymutex, 1);
|
||||
prev_p = NULL;
|
||||
for (p = keyhead; p != NULL; p = p->next) {
|
||||
if (p->id == id && p->key == key)
|
||||
goto Done;
|
||||
/* Sanity check. These states should never happen but if
|
||||
* they do we must abort. Otherwise we'll end up spinning in
|
||||
* in a tight loop with the lock held. A similar check is done
|
||||
* in pystate.c tstate_delete_common(). */
|
||||
if (p == prev_p)
|
||||
Py_FatalError("tls find_key: small circular list(!)");
|
||||
prev_p = p;
|
||||
if (p->next == keyhead)
|
||||
Py_FatalError("tls find_key: circular list(!)");
|
||||
}
|
||||
if (value == NULL) {
|
||||
assert(p == NULL);
|
||||
goto Done;
|
||||
}
|
||||
p = (struct key *)malloc(sizeof(struct key));
|
||||
if (p != NULL) {
|
||||
p->id = id;
|
||||
p->key = key;
|
||||
p->value = value;
|
||||
p->next = keyhead;
|
||||
keyhead = p;
|
||||
}
|
||||
Done:
|
||||
PyThread_release_lock(keymutex);
|
||||
return p;
|
||||
PyThread_release_lock(keymutex);
|
||||
return p;
|
||||
}
|
||||
|
||||
/* Return a new key. This must be called before any other functions in
|
||||
|
@ -304,32 +304,32 @@ find_key(int key, void *value)
|
|||
int
|
||||
PyThread_create_key(void)
|
||||
{
|
||||
/* All parts of this function are wrong if it's called by multiple
|
||||
* threads simultaneously.
|
||||
*/
|
||||
if (keymutex == NULL)
|
||||
keymutex = PyThread_allocate_lock();
|
||||
return ++nkeys;
|
||||
/* All parts of this function are wrong if it's called by multiple
|
||||
* threads simultaneously.
|
||||
*/
|
||||
if (keymutex == NULL)
|
||||
keymutex = PyThread_allocate_lock();
|
||||
return ++nkeys;
|
||||
}
|
||||
|
||||
/* Forget the associations for key across *all* threads. */
|
||||
void
|
||||
PyThread_delete_key(int key)
|
||||
{
|
||||
struct key *p, **q;
|
||||
struct key *p, **q;
|
||||
|
||||
PyThread_acquire_lock(keymutex, 1);
|
||||
q = &keyhead;
|
||||
while ((p = *q) != NULL) {
|
||||
if (p->key == key) {
|
||||
*q = p->next;
|
||||
free((void *)p);
|
||||
/* NB This does *not* free p->value! */
|
||||
}
|
||||
else
|
||||
q = &p->next;
|
||||
}
|
||||
PyThread_release_lock(keymutex);
|
||||
PyThread_acquire_lock(keymutex, 1);
|
||||
q = &keyhead;
|
||||
while ((p = *q) != NULL) {
|
||||
if (p->key == key) {
|
||||
*q = p->next;
|
||||
free((void *)p);
|
||||
/* NB This does *not* free p->value! */
|
||||
}
|
||||
else
|
||||
q = &p->next;
|
||||
}
|
||||
PyThread_release_lock(keymutex);
|
||||
}
|
||||
|
||||
/* Confusing: If the current thread has an association for key,
|
||||
|
@ -341,14 +341,14 @@ PyThread_delete_key(int key)
|
|||
int
|
||||
PyThread_set_key_value(int key, void *value)
|
||||
{
|
||||
struct key *p;
|
||||
struct key *p;
|
||||
|
||||
assert(value != NULL);
|
||||
p = find_key(key, value);
|
||||
if (p == NULL)
|
||||
return -1;
|
||||
else
|
||||
return 0;
|
||||
assert(value != NULL);
|
||||
p = find_key(key, value);
|
||||
if (p == NULL)
|
||||
return -1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Retrieve the value associated with key in the current thread, or NULL
|
||||
|
@ -357,34 +357,34 @@ PyThread_set_key_value(int key, void *value)
|
|||
void *
|
||||
PyThread_get_key_value(int key)
|
||||
{
|
||||
struct key *p = find_key(key, NULL);
|
||||
struct key *p = find_key(key, NULL);
|
||||
|
||||
if (p == NULL)
|
||||
return NULL;
|
||||
else
|
||||
return p->value;
|
||||
if (p == NULL)
|
||||
return NULL;
|
||||
else
|
||||
return p->value;
|
||||
}
|
||||
|
||||
/* Forget the current thread's association for key, if any. */
|
||||
void
|
||||
PyThread_delete_key_value(int key)
|
||||
{
|
||||
long id = PyThread_get_thread_ident();
|
||||
struct key *p, **q;
|
||||
long id = PyThread_get_thread_ident();
|
||||
struct key *p, **q;
|
||||
|
||||
PyThread_acquire_lock(keymutex, 1);
|
||||
q = &keyhead;
|
||||
while ((p = *q) != NULL) {
|
||||
if (p->key == key && p->id == id) {
|
||||
*q = p->next;
|
||||
free((void *)p);
|
||||
/* NB This does *not* free p->value! */
|
||||
break;
|
||||
}
|
||||
else
|
||||
q = &p->next;
|
||||
}
|
||||
PyThread_release_lock(keymutex);
|
||||
PyThread_acquire_lock(keymutex, 1);
|
||||
q = &keyhead;
|
||||
while ((p = *q) != NULL) {
|
||||
if (p->key == key && p->id == id) {
|
||||
*q = p->next;
|
||||
free((void *)p);
|
||||
/* NB This does *not* free p->value! */
|
||||
break;
|
||||
}
|
||||
else
|
||||
q = &p->next;
|
||||
}
|
||||
PyThread_release_lock(keymutex);
|
||||
}
|
||||
|
||||
/* Forget everything not associated with the current thread id.
|
||||
|
@ -395,27 +395,27 @@ PyThread_delete_key_value(int key)
|
|||
void
|
||||
PyThread_ReInitTLS(void)
|
||||
{
|
||||
long id = PyThread_get_thread_ident();
|
||||
struct key *p, **q;
|
||||
long id = PyThread_get_thread_ident();
|
||||
struct key *p, **q;
|
||||
|
||||
if (!keymutex)
|
||||
return;
|
||||
|
||||
/* As with interpreter_lock in PyEval_ReInitThreads()
|
||||
we just create a new lock without freeing the old one */
|
||||
keymutex = PyThread_allocate_lock();
|
||||
if (!keymutex)
|
||||
return;
|
||||
|
||||
/* Delete all keys which do not match the current thread id */
|
||||
q = &keyhead;
|
||||
while ((p = *q) != NULL) {
|
||||
if (p->id != id) {
|
||||
*q = p->next;
|
||||
free((void *)p);
|
||||
/* NB This does *not* free p->value! */
|
||||
}
|
||||
else
|
||||
q = &p->next;
|
||||
}
|
||||
/* As with interpreter_lock in PyEval_ReInitThreads()
|
||||
we just create a new lock without freeing the old one */
|
||||
keymutex = PyThread_allocate_lock();
|
||||
|
||||
/* Delete all keys which do not match the current thread id */
|
||||
q = &keyhead;
|
||||
while ((p = *q) != NULL) {
|
||||
if (p->id != id) {
|
||||
*q = p->next;
|
||||
free((void *)p);
|
||||
/* NB This does *not* free p->value! */
|
||||
}
|
||||
else
|
||||
q = &p->next;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* Py_HAVE_NATIVE_TLS */
|
||||
|
|
|
@ -19,8 +19,8 @@ extern int exit_thread(int);
|
|||
|
||||
/* Use an atomic counter and a semaphore for maximum speed. */
|
||||
typedef struct fastmutex {
|
||||
sem_id sem;
|
||||
atomic_t count;
|
||||
sem_id sem;
|
||||
atomic_t count;
|
||||
} fastmutex_t;
|
||||
|
||||
|
||||
|
@ -33,49 +33,49 @@ static int fastmutex_unlock(fastmutex_t * mutex);
|
|||
|
||||
static int fastmutex_create(const char *name, fastmutex_t * mutex)
|
||||
{
|
||||
mutex->count = 0;
|
||||
mutex->sem = create_semaphore(name, 0, 0);
|
||||
return (mutex->sem < 0) ? -1 : 0;
|
||||
mutex->count = 0;
|
||||
mutex->sem = create_semaphore(name, 0, 0);
|
||||
return (mutex->sem < 0) ? -1 : 0;
|
||||
}
|
||||
|
||||
|
||||
static int fastmutex_destroy(fastmutex_t * mutex)
|
||||
{
|
||||
if (fastmutex_timedlock(mutex, 0) == 0 || errno == EWOULDBLOCK) {
|
||||
return delete_semaphore(mutex->sem);
|
||||
}
|
||||
return 0;
|
||||
if (fastmutex_timedlock(mutex, 0) == 0 || errno == EWOULDBLOCK) {
|
||||
return delete_semaphore(mutex->sem);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int fastmutex_lock(fastmutex_t * mutex)
|
||||
{
|
||||
atomic_t prev = atomic_add(&mutex->count, 1);
|
||||
if (prev > 0)
|
||||
return lock_semaphore(mutex->sem);
|
||||
return 0;
|
||||
atomic_t prev = atomic_add(&mutex->count, 1);
|
||||
if (prev > 0)
|
||||
return lock_semaphore(mutex->sem);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int fastmutex_timedlock(fastmutex_t * mutex, bigtime_t timeout)
|
||||
{
|
||||
atomic_t prev = atomic_add(&mutex->count, 1);
|
||||
if (prev > 0)
|
||||
return lock_semaphore_x(mutex->sem, 1, 0, timeout);
|
||||
return 0;
|
||||
atomic_t prev = atomic_add(&mutex->count, 1);
|
||||
if (prev > 0)
|
||||
return lock_semaphore_x(mutex->sem, 1, 0, timeout);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int fastmutex_unlock(fastmutex_t * mutex)
|
||||
{
|
||||
atomic_t prev = atomic_add(&mutex->count, -1);
|
||||
if (prev > 1)
|
||||
return unlock_semaphore(mutex->sem);
|
||||
return 0;
|
||||
atomic_t prev = atomic_add(&mutex->count, -1);
|
||||
if (prev > 1)
|
||||
return unlock_semaphore(mutex->sem);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#endif /* FASTLOCK */
|
||||
#endif /* FASTLOCK */
|
||||
|
||||
|
||||
/*
|
||||
|
@ -84,8 +84,8 @@ static int fastmutex_unlock(fastmutex_t * mutex)
|
|||
*/
|
||||
static void PyThread__init_thread(void)
|
||||
{
|
||||
/* Do nothing. */
|
||||
return;
|
||||
/* Do nothing. */
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
@ -98,48 +98,48 @@ static atomic_t thread_count = 0;
|
|||
|
||||
long PyThread_start_new_thread(void (*func) (void *), void *arg)
|
||||
{
|
||||
status_t success = -1;
|
||||
thread_id tid;
|
||||
char name[OS_NAME_LENGTH];
|
||||
atomic_t this_thread;
|
||||
status_t success = -1;
|
||||
thread_id tid;
|
||||
char name[OS_NAME_LENGTH];
|
||||
atomic_t this_thread;
|
||||
|
||||
dprintf(("PyThread_start_new_thread called\n"));
|
||||
dprintf(("PyThread_start_new_thread called\n"));
|
||||
|
||||
this_thread = atomic_add(&thread_count, 1);
|
||||
PyOS_snprintf(name, sizeof(name), "python thread (%d)", this_thread);
|
||||
this_thread = atomic_add(&thread_count, 1);
|
||||
PyOS_snprintf(name, sizeof(name), "python thread (%d)", this_thread);
|
||||
|
||||
tid = spawn_thread(name, func, NORMAL_PRIORITY, 0, arg);
|
||||
if (tid < 0) {
|
||||
dprintf(("PyThread_start_new_thread spawn_thread failed: %s\n", strerror(errno)));
|
||||
} else {
|
||||
success = resume_thread(tid);
|
||||
if (success < 0) {
|
||||
dprintf(("PyThread_start_new_thread resume_thread failed: %s\n", strerror(errno)));
|
||||
}
|
||||
}
|
||||
tid = spawn_thread(name, func, NORMAL_PRIORITY, 0, arg);
|
||||
if (tid < 0) {
|
||||
dprintf(("PyThread_start_new_thread spawn_thread failed: %s\n", strerror(errno)));
|
||||
} else {
|
||||
success = resume_thread(tid);
|
||||
if (success < 0) {
|
||||
dprintf(("PyThread_start_new_thread resume_thread failed: %s\n", strerror(errno)));
|
||||
}
|
||||
}
|
||||
|
||||
return (success < 0 ? -1 : tid);
|
||||
return (success < 0 ? -1 : tid);
|
||||
}
|
||||
|
||||
|
||||
long PyThread_get_thread_ident(void)
|
||||
{
|
||||
return get_thread_id(NULL);
|
||||
return get_thread_id(NULL);
|
||||
}
|
||||
|
||||
|
||||
void PyThread_exit_thread(void)
|
||||
{
|
||||
dprintf(("PyThread_exit_thread called\n"));
|
||||
dprintf(("PyThread_exit_thread called\n"));
|
||||
|
||||
/* Thread-safe way to read a variable without a mutex: */
|
||||
if (atomic_add(&thread_count, 0) == 0) {
|
||||
/* No threads around, so exit main(). */
|
||||
exit(0);
|
||||
} else {
|
||||
/* We're a thread */
|
||||
exit_thread(0);
|
||||
}
|
||||
/* Thread-safe way to read a variable without a mutex: */
|
||||
if (atomic_add(&thread_count, 0) == 0) {
|
||||
/* No threads around, so exit main(). */
|
||||
exit(0);
|
||||
} else {
|
||||
/* We're a thread */
|
||||
exit_thread(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -153,107 +153,107 @@ static atomic_t lock_count = 0;
|
|||
PyThread_type_lock PyThread_allocate_lock(void)
|
||||
{
|
||||
#ifdef FASTLOCK
|
||||
fastmutex_t *lock;
|
||||
fastmutex_t *lock;
|
||||
#else
|
||||
sem_id sema;
|
||||
sem_id sema;
|
||||
#endif
|
||||
char name[OS_NAME_LENGTH];
|
||||
atomic_t this_lock;
|
||||
char name[OS_NAME_LENGTH];
|
||||
atomic_t this_lock;
|
||||
|
||||
dprintf(("PyThread_allocate_lock called\n"));
|
||||
dprintf(("PyThread_allocate_lock called\n"));
|
||||
|
||||
#ifdef FASTLOCK
|
||||
lock = (fastmutex_t *) malloc(sizeof(fastmutex_t));
|
||||
if (lock == NULL) {
|
||||
dprintf(("PyThread_allocate_lock failed: out of memory\n"));
|
||||
return (PyThread_type_lock) NULL;
|
||||
}
|
||||
lock = (fastmutex_t *) malloc(sizeof(fastmutex_t));
|
||||
if (lock == NULL) {
|
||||
dprintf(("PyThread_allocate_lock failed: out of memory\n"));
|
||||
return (PyThread_type_lock) NULL;
|
||||
}
|
||||
#endif
|
||||
this_lock = atomic_add(&lock_count, 1);
|
||||
PyOS_snprintf(name, sizeof(name), "python lock (%d)", this_lock);
|
||||
this_lock = atomic_add(&lock_count, 1);
|
||||
PyOS_snprintf(name, sizeof(name), "python lock (%d)", this_lock);
|
||||
|
||||
#ifdef FASTLOCK
|
||||
if (fastmutex_create(name, lock) < 0) {
|
||||
dprintf(("PyThread_allocate_lock failed: %s\n",
|
||||
strerror(errno)));
|
||||
free(lock);
|
||||
lock = NULL;
|
||||
}
|
||||
dprintf(("PyThread_allocate_lock()-> %p\n", lock));
|
||||
return (PyThread_type_lock) lock;
|
||||
if (fastmutex_create(name, lock) < 0) {
|
||||
dprintf(("PyThread_allocate_lock failed: %s\n",
|
||||
strerror(errno)));
|
||||
free(lock);
|
||||
lock = NULL;
|
||||
}
|
||||
dprintf(("PyThread_allocate_lock()-> %p\n", lock));
|
||||
return (PyThread_type_lock) lock;
|
||||
#else
|
||||
sema = create_semaphore(name, 1, 0);
|
||||
if (sema < 0) {
|
||||
dprintf(("PyThread_allocate_lock failed: %s\n",
|
||||
strerror(errno)));
|
||||
sema = 0;
|
||||
}
|
||||
dprintf(("PyThread_allocate_lock()-> %p\n", sema));
|
||||
return (PyThread_type_lock) sema;
|
||||
sema = create_semaphore(name, 1, 0);
|
||||
if (sema < 0) {
|
||||
dprintf(("PyThread_allocate_lock failed: %s\n",
|
||||
strerror(errno)));
|
||||
sema = 0;
|
||||
}
|
||||
dprintf(("PyThread_allocate_lock()-> %p\n", sema));
|
||||
return (PyThread_type_lock) sema;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void PyThread_free_lock(PyThread_type_lock lock)
|
||||
{
|
||||
dprintf(("PyThread_free_lock(%p) called\n", lock));
|
||||
dprintf(("PyThread_free_lock(%p) called\n", lock));
|
||||
|
||||
#ifdef FASTLOCK
|
||||
if (fastmutex_destroy((fastmutex_t *) lock) < 0) {
|
||||
dprintf(("PyThread_free_lock(%p) failed: %s\n", lock,
|
||||
strerror(errno)));
|
||||
}
|
||||
free(lock);
|
||||
if (fastmutex_destroy((fastmutex_t *) lock) < 0) {
|
||||
dprintf(("PyThread_free_lock(%p) failed: %s\n", lock,
|
||||
strerror(errno)));
|
||||
}
|
||||
free(lock);
|
||||
#else
|
||||
if (delete_semaphore((sem_id) lock) < 0) {
|
||||
dprintf(("PyThread_free_lock(%p) failed: %s\n", lock,
|
||||
strerror(errno)));
|
||||
}
|
||||
if (delete_semaphore((sem_id) lock) < 0) {
|
||||
dprintf(("PyThread_free_lock(%p) failed: %s\n", lock,
|
||||
strerror(errno)));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
int PyThread_acquire_lock(PyThread_type_lock lock, int waitflag)
|
||||
{
|
||||
int retval;
|
||||
int retval;
|
||||
|
||||
dprintf(("PyThread_acquire_lock(%p, %d) called\n", lock,
|
||||
waitflag));
|
||||
dprintf(("PyThread_acquire_lock(%p, %d) called\n", lock,
|
||||
waitflag));
|
||||
|
||||
#ifdef FASTLOCK
|
||||
if (waitflag)
|
||||
retval = fastmutex_lock((fastmutex_t *) lock);
|
||||
else
|
||||
retval = fastmutex_timedlock((fastmutex_t *) lock, 0);
|
||||
if (waitflag)
|
||||
retval = fastmutex_lock((fastmutex_t *) lock);
|
||||
else
|
||||
retval = fastmutex_timedlock((fastmutex_t *) lock, 0);
|
||||
#else
|
||||
if (waitflag)
|
||||
retval = lock_semaphore((sem_id) lock);
|
||||
else
|
||||
retval = lock_semaphore_x((sem_id) lock, 1, 0, 0);
|
||||
if (waitflag)
|
||||
retval = lock_semaphore((sem_id) lock);
|
||||
else
|
||||
retval = lock_semaphore_x((sem_id) lock, 1, 0, 0);
|
||||
#endif
|
||||
if (retval < 0) {
|
||||
dprintf(("PyThread_acquire_lock(%p, %d) failed: %s\n",
|
||||
lock, waitflag, strerror(errno)));
|
||||
}
|
||||
dprintf(("PyThread_acquire_lock(%p, %d)-> %d\n", lock, waitflag,
|
||||
retval));
|
||||
return retval < 0 ? 0 : 1;
|
||||
if (retval < 0) {
|
||||
dprintf(("PyThread_acquire_lock(%p, %d) failed: %s\n",
|
||||
lock, waitflag, strerror(errno)));
|
||||
}
|
||||
dprintf(("PyThread_acquire_lock(%p, %d)-> %d\n", lock, waitflag,
|
||||
retval));
|
||||
return retval < 0 ? 0 : 1;
|
||||
}
|
||||
|
||||
|
||||
void PyThread_release_lock(PyThread_type_lock lock)
|
||||
{
|
||||
dprintf(("PyThread_release_lock(%p) called\n", lock));
|
||||
dprintf(("PyThread_release_lock(%p) called\n", lock));
|
||||
|
||||
#ifdef FASTLOCK
|
||||
if (fastmutex_unlock((fastmutex_t *) lock) < 0) {
|
||||
dprintf(("PyThread_release_lock(%p) failed: %s\n", lock,
|
||||
strerror(errno)));
|
||||
}
|
||||
if (fastmutex_unlock((fastmutex_t *) lock) < 0) {
|
||||
dprintf(("PyThread_release_lock(%p) failed: %s\n", lock,
|
||||
strerror(errno)));
|
||||
}
|
||||
#else
|
||||
if (unlock_semaphore((sem_id) lock) < 0) {
|
||||
dprintf(("PyThread_release_lock(%p) failed: %s\n", lock,
|
||||
strerror(errno)));
|
||||
}
|
||||
if (unlock_semaphore((sem_id) lock) < 0) {
|
||||
dprintf(("PyThread_release_lock(%p) failed: %s\n", lock,
|
||||
strerror(errno)));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -7,8 +7,8 @@
|
|||
* in the Be Developer's Newsletter, Issue #26 (http://www.be.com/).
|
||||
*/
|
||||
typedef struct benaphore {
|
||||
sem_id _sem;
|
||||
int32 _atom;
|
||||
sem_id _sem;
|
||||
int32 _atom;
|
||||
} benaphore_t;
|
||||
|
||||
static status_t benaphore_create( const char *name, benaphore_t *ben );
|
||||
|
@ -19,79 +19,79 @@ static status_t benaphore_unlock( benaphore_t *ben );
|
|||
|
||||
static status_t benaphore_create( const char *name, benaphore_t *ben )
|
||||
{
|
||||
if( ben != NULL ) {
|
||||
ben->_atom = 0;
|
||||
ben->_sem = create_sem( 0, name );
|
||||
|
||||
if( ben->_sem < B_NO_ERROR ) {
|
||||
return B_BAD_SEM_ID;
|
||||
}
|
||||
} else {
|
||||
return EFAULT;
|
||||
}
|
||||
|
||||
return EOK;
|
||||
if( ben != NULL ) {
|
||||
ben->_atom = 0;
|
||||
ben->_sem = create_sem( 0, name );
|
||||
|
||||
if( ben->_sem < B_NO_ERROR ) {
|
||||
return B_BAD_SEM_ID;
|
||||
}
|
||||
} else {
|
||||
return EFAULT;
|
||||
}
|
||||
|
||||
return EOK;
|
||||
}
|
||||
|
||||
static status_t benaphore_destroy( benaphore_t *ben )
|
||||
{
|
||||
if( ben->_sem >= B_NO_ERROR ) {
|
||||
status_t retval = benaphore_timedlock( ben, 0 );
|
||||
|
||||
if( retval == EOK || retval == EWOULDBLOCK ) {
|
||||
status_t del_retval = delete_sem( ben->_sem );
|
||||
|
||||
return del_retval;
|
||||
}
|
||||
}
|
||||
if( ben->_sem >= B_NO_ERROR ) {
|
||||
status_t retval = benaphore_timedlock( ben, 0 );
|
||||
|
||||
return B_BAD_SEM_ID;
|
||||
if( retval == EOK || retval == EWOULDBLOCK ) {
|
||||
status_t del_retval = delete_sem( ben->_sem );
|
||||
|
||||
return del_retval;
|
||||
}
|
||||
}
|
||||
|
||||
return B_BAD_SEM_ID;
|
||||
}
|
||||
|
||||
static status_t benaphore_lock( benaphore_t *ben )
|
||||
{
|
||||
int32 prev = atomic_add( &(ben->_atom), 1 );
|
||||
|
||||
if( prev > 0 ) {
|
||||
return acquire_sem( ben->_sem );
|
||||
}
|
||||
|
||||
return EOK;
|
||||
int32 prev = atomic_add( &(ben->_atom), 1 );
|
||||
|
||||
if( prev > 0 ) {
|
||||
return acquire_sem( ben->_sem );
|
||||
}
|
||||
|
||||
return EOK;
|
||||
}
|
||||
|
||||
static status_t benaphore_timedlock( benaphore_t *ben, bigtime_t micros )
|
||||
{
|
||||
int32 prev = atomic_add( &(ben->_atom), 1 );
|
||||
|
||||
if( prev > 0 ) {
|
||||
status_t retval = acquire_sem_etc( ben->_sem, 1, B_TIMEOUT, micros );
|
||||
|
||||
switch( retval ) {
|
||||
case B_WOULD_BLOCK: /* Fall through... */
|
||||
case B_TIMED_OUT:
|
||||
return EWOULDBLOCK;
|
||||
break;
|
||||
case B_OK:
|
||||
return EOK;
|
||||
break;
|
||||
default:
|
||||
return retval;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return EOK;
|
||||
int32 prev = atomic_add( &(ben->_atom), 1 );
|
||||
|
||||
if( prev > 0 ) {
|
||||
status_t retval = acquire_sem_etc( ben->_sem, 1, B_TIMEOUT, micros );
|
||||
|
||||
switch( retval ) {
|
||||
case B_WOULD_BLOCK: /* Fall through... */
|
||||
case B_TIMED_OUT:
|
||||
return EWOULDBLOCK;
|
||||
break;
|
||||
case B_OK:
|
||||
return EOK;
|
||||
break;
|
||||
default:
|
||||
return retval;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return EOK;
|
||||
}
|
||||
|
||||
static status_t benaphore_unlock( benaphore_t *ben )
|
||||
{
|
||||
int32 prev = atomic_add( &(ben->_atom), -1 );
|
||||
|
||||
if( prev > 1 ) {
|
||||
return release_sem( ben->_sem );
|
||||
}
|
||||
|
||||
return EOK;
|
||||
int32 prev = atomic_add( &(ben->_atom), -1 );
|
||||
|
||||
if( prev > 1 ) {
|
||||
return release_sem( ben->_sem );
|
||||
}
|
||||
|
||||
return EOK;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
|
@ -99,8 +99,8 @@ static status_t benaphore_unlock( benaphore_t *ben )
|
|||
*/
|
||||
static void PyThread__init_thread( void )
|
||||
{
|
||||
/* Do nothing. */
|
||||
return;
|
||||
/* Do nothing. */
|
||||
return;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
|
@ -114,52 +114,52 @@ static int32 thread_count = 0;
|
|||
|
||||
long PyThread_start_new_thread( void (*func)(void *), void *arg )
|
||||
{
|
||||
status_t success = 0;
|
||||
thread_id tid;
|
||||
char name[B_OS_NAME_LENGTH];
|
||||
int32 this_thread;
|
||||
status_t success = 0;
|
||||
thread_id tid;
|
||||
char name[B_OS_NAME_LENGTH];
|
||||
int32 this_thread;
|
||||
|
||||
dprintf(("PyThread_start_new_thread called\n"));
|
||||
dprintf(("PyThread_start_new_thread called\n"));
|
||||
|
||||
/* We are so very thread-safe... */
|
||||
this_thread = atomic_add( &thread_count, 1 );
|
||||
PyOS_snprintf(name, sizeof(name),
|
||||
"python thread (%d)", this_thread );
|
||||
/* We are so very thread-safe... */
|
||||
this_thread = atomic_add( &thread_count, 1 );
|
||||
PyOS_snprintf(name, sizeof(name),
|
||||
"python thread (%d)", this_thread );
|
||||
|
||||
tid = spawn_thread( (thread_func)func, name,
|
||||
B_NORMAL_PRIORITY, arg );
|
||||
if( tid > B_NO_ERROR ) {
|
||||
success = resume_thread( tid );
|
||||
}
|
||||
tid = spawn_thread( (thread_func)func, name,
|
||||
B_NORMAL_PRIORITY, arg );
|
||||
if( tid > B_NO_ERROR ) {
|
||||
success = resume_thread( tid );
|
||||
}
|
||||
|
||||
return ( success == B_NO_ERROR ? tid : -1 );
|
||||
return ( success == B_NO_ERROR ? tid : -1 );
|
||||
}
|
||||
|
||||
long PyThread_get_thread_ident( void )
|
||||
{
|
||||
/* Presumed to return the current thread's ID... */
|
||||
thread_id tid;
|
||||
tid = find_thread( NULL );
|
||||
|
||||
return ( tid != B_NAME_NOT_FOUND ? tid : -1 );
|
||||
/* Presumed to return the current thread's ID... */
|
||||
thread_id tid;
|
||||
tid = find_thread( NULL );
|
||||
|
||||
return ( tid != B_NAME_NOT_FOUND ? tid : -1 );
|
||||
}
|
||||
|
||||
void PyThread_exit_thread( void )
|
||||
{
|
||||
int32 threads;
|
||||
int32 threads;
|
||||
|
||||
dprintf(("PyThread_exit_thread called\n"));
|
||||
dprintf(("PyThread_exit_thread called\n"));
|
||||
|
||||
/* Thread-safe way to read a variable without a mutex: */
|
||||
threads = atomic_add( &thread_count, 0 );
|
||||
/* Thread-safe way to read a variable without a mutex: */
|
||||
threads = atomic_add( &thread_count, 0 );
|
||||
|
||||
if( threads == 0 ) {
|
||||
/* No threads around, so exit main(). */
|
||||
exit(0);
|
||||
} else {
|
||||
/* Oh, we're a thread, let's try to exit gracefully... */
|
||||
exit_thread( B_NO_ERROR );
|
||||
}
|
||||
if( threads == 0 ) {
|
||||
/* No threads around, so exit main(). */
|
||||
exit(0);
|
||||
} else {
|
||||
/* Oh, we're a thread, let's try to exit gracefully... */
|
||||
exit_thread( B_NO_ERROR );
|
||||
}
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
|
@ -170,79 +170,79 @@ static int32 lock_count = 0;
|
|||
|
||||
PyThread_type_lock PyThread_allocate_lock( void )
|
||||
{
|
||||
benaphore_t *lock;
|
||||
status_t retval;
|
||||
char name[B_OS_NAME_LENGTH];
|
||||
int32 this_lock;
|
||||
|
||||
dprintf(("PyThread_allocate_lock called\n"));
|
||||
benaphore_t *lock;
|
||||
status_t retval;
|
||||
char name[B_OS_NAME_LENGTH];
|
||||
int32 this_lock;
|
||||
|
||||
lock = (benaphore_t *)malloc( sizeof( benaphore_t ) );
|
||||
if( lock == NULL ) {
|
||||
/* TODO: that's bad, raise MemoryError */
|
||||
return (PyThread_type_lock)NULL;
|
||||
}
|
||||
dprintf(("PyThread_allocate_lock called\n"));
|
||||
|
||||
this_lock = atomic_add( &lock_count, 1 );
|
||||
PyOS_snprintf(name, sizeof(name), "python lock (%d)", this_lock);
|
||||
lock = (benaphore_t *)malloc( sizeof( benaphore_t ) );
|
||||
if( lock == NULL ) {
|
||||
/* TODO: that's bad, raise MemoryError */
|
||||
return (PyThread_type_lock)NULL;
|
||||
}
|
||||
|
||||
retval = benaphore_create( name, lock );
|
||||
if( retval != EOK ) {
|
||||
/* TODO: that's bad, raise an exception */
|
||||
return (PyThread_type_lock)NULL;
|
||||
}
|
||||
this_lock = atomic_add( &lock_count, 1 );
|
||||
PyOS_snprintf(name, sizeof(name), "python lock (%d)", this_lock);
|
||||
|
||||
dprintf(("PyThread_allocate_lock() -> %p\n", lock));
|
||||
return (PyThread_type_lock) lock;
|
||||
retval = benaphore_create( name, lock );
|
||||
if( retval != EOK ) {
|
||||
/* TODO: that's bad, raise an exception */
|
||||
return (PyThread_type_lock)NULL;
|
||||
}
|
||||
|
||||
dprintf(("PyThread_allocate_lock() -> %p\n", lock));
|
||||
return (PyThread_type_lock) lock;
|
||||
}
|
||||
|
||||
void PyThread_free_lock( PyThread_type_lock lock )
|
||||
{
|
||||
status_t retval;
|
||||
status_t retval;
|
||||
|
||||
dprintf(("PyThread_free_lock(%p) called\n", lock));
|
||||
|
||||
retval = benaphore_destroy( (benaphore_t *)lock );
|
||||
if( retval != EOK ) {
|
||||
/* TODO: that's bad, raise an exception */
|
||||
return;
|
||||
}
|
||||
dprintf(("PyThread_free_lock(%p) called\n", lock));
|
||||
|
||||
retval = benaphore_destroy( (benaphore_t *)lock );
|
||||
if( retval != EOK ) {
|
||||
/* TODO: that's bad, raise an exception */
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
int PyThread_acquire_lock( PyThread_type_lock lock, int waitflag )
|
||||
{
|
||||
int success;
|
||||
status_t retval;
|
||||
int success;
|
||||
status_t retval;
|
||||
|
||||
dprintf(("PyThread_acquire_lock(%p, %d) called\n", lock, waitflag));
|
||||
dprintf(("PyThread_acquire_lock(%p, %d) called\n", lock, waitflag));
|
||||
|
||||
if( waitflag ) {
|
||||
retval = benaphore_lock( (benaphore_t *)lock );
|
||||
} else {
|
||||
retval = benaphore_timedlock( (benaphore_t *)lock, 0 );
|
||||
}
|
||||
|
||||
if( retval == EOK ) {
|
||||
success = 1;
|
||||
} else {
|
||||
success = 0;
|
||||
|
||||
/* TODO: that's bad, raise an exception */
|
||||
}
|
||||
if( waitflag ) {
|
||||
retval = benaphore_lock( (benaphore_t *)lock );
|
||||
} else {
|
||||
retval = benaphore_timedlock( (benaphore_t *)lock, 0 );
|
||||
}
|
||||
|
||||
dprintf(("PyThread_acquire_lock(%p, %d) -> %d\n", lock, waitflag, success));
|
||||
return success;
|
||||
if( retval == EOK ) {
|
||||
success = 1;
|
||||
} else {
|
||||
success = 0;
|
||||
|
||||
/* TODO: that's bad, raise an exception */
|
||||
}
|
||||
|
||||
dprintf(("PyThread_acquire_lock(%p, %d) -> %d\n", lock, waitflag, success));
|
||||
return success;
|
||||
}
|
||||
|
||||
void PyThread_release_lock( PyThread_type_lock lock )
|
||||
{
|
||||
status_t retval;
|
||||
|
||||
dprintf(("PyThread_release_lock(%p) called\n", lock));
|
||||
|
||||
retval = benaphore_unlock( (benaphore_t *)lock );
|
||||
if( retval != EOK ) {
|
||||
/* TODO: that's bad, raise an exception */
|
||||
return;
|
||||
}
|
||||
status_t retval;
|
||||
|
||||
dprintf(("PyThread_release_lock(%p) called\n", lock));
|
||||
|
||||
retval = benaphore_unlock( (benaphore_t *)lock );
|
||||
if( retval != EOK ) {
|
||||
/* TODO: that's bad, raise an exception */
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,12 +14,12 @@ static void
|
|||
PyThread__init_thread(void)
|
||||
{
|
||||
#ifndef HURD_C_THREADS
|
||||
/* Roland McGrath said this should not be used since this is
|
||||
done while linking to threads */
|
||||
cthread_init();
|
||||
/* Roland McGrath said this should not be used since this is
|
||||
done while linking to threads */
|
||||
cthread_init();
|
||||
#else
|
||||
/* do nothing */
|
||||
;
|
||||
;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -29,34 +29,34 @@ PyThread__init_thread(void)
|
|||
long
|
||||
PyThread_start_new_thread(void (*func)(void *), void *arg)
|
||||
{
|
||||
int success = 0; /* init not needed when SOLARIS_THREADS and */
|
||||
/* C_THREADS implemented properly */
|
||||
int success = 0; /* init not needed when SOLARIS_THREADS and */
|
||||
/* C_THREADS implemented properly */
|
||||
|
||||
dprintf(("PyThread_start_new_thread called\n"));
|
||||
if (!initialized)
|
||||
PyThread_init_thread();
|
||||
/* looks like solaris detaches the thread to never rejoin
|
||||
* so well do it here
|
||||
*/
|
||||
cthread_detach(cthread_fork((cthread_fn_t) func, arg));
|
||||
return success < 0 ? -1 : 0;
|
||||
dprintf(("PyThread_start_new_thread called\n"));
|
||||
if (!initialized)
|
||||
PyThread_init_thread();
|
||||
/* looks like solaris detaches the thread to never rejoin
|
||||
* so well do it here
|
||||
*/
|
||||
cthread_detach(cthread_fork((cthread_fn_t) func, arg));
|
||||
return success < 0 ? -1 : 0;
|
||||
}
|
||||
|
||||
long
|
||||
PyThread_get_thread_ident(void)
|
||||
{
|
||||
if (!initialized)
|
||||
PyThread_init_thread();
|
||||
return (long) cthread_self();
|
||||
if (!initialized)
|
||||
PyThread_init_thread();
|
||||
return (long) cthread_self();
|
||||
}
|
||||
|
||||
void
|
||||
PyThread_exit_thread(void)
|
||||
{
|
||||
dprintf(("PyThread_exit_thread called\n"));
|
||||
if (!initialized)
|
||||
exit(0);
|
||||
cthread_exit(0);
|
||||
dprintf(("PyThread_exit_thread called\n"));
|
||||
if (!initialized)
|
||||
exit(0);
|
||||
cthread_exit(0);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -65,48 +65,48 @@ PyThread_exit_thread(void)
|
|||
PyThread_type_lock
|
||||
PyThread_allocate_lock(void)
|
||||
{
|
||||
mutex_t lock;
|
||||
mutex_t lock;
|
||||
|
||||
dprintf(("PyThread_allocate_lock called\n"));
|
||||
if (!initialized)
|
||||
PyThread_init_thread();
|
||||
dprintf(("PyThread_allocate_lock called\n"));
|
||||
if (!initialized)
|
||||
PyThread_init_thread();
|
||||
|
||||
lock = mutex_alloc();
|
||||
if (mutex_init(lock)) {
|
||||
perror("mutex_init");
|
||||
free((void *) lock);
|
||||
lock = 0;
|
||||
}
|
||||
dprintf(("PyThread_allocate_lock() -> %p\n", lock));
|
||||
return (PyThread_type_lock) lock;
|
||||
lock = mutex_alloc();
|
||||
if (mutex_init(lock)) {
|
||||
perror("mutex_init");
|
||||
free((void *) lock);
|
||||
lock = 0;
|
||||
}
|
||||
dprintf(("PyThread_allocate_lock() -> %p\n", lock));
|
||||
return (PyThread_type_lock) lock;
|
||||
}
|
||||
|
||||
void
|
||||
PyThread_free_lock(PyThread_type_lock lock)
|
||||
{
|
||||
dprintf(("PyThread_free_lock(%p) called\n", lock));
|
||||
mutex_free(lock);
|
||||
dprintf(("PyThread_free_lock(%p) called\n", lock));
|
||||
mutex_free(lock);
|
||||
}
|
||||
|
||||
int
|
||||
PyThread_acquire_lock(PyThread_type_lock lock, int waitflag)
|
||||
{
|
||||
int success = FALSE;
|
||||
int success = FALSE;
|
||||
|
||||
dprintf(("PyThread_acquire_lock(%p, %d) called\n", lock, waitflag));
|
||||
if (waitflag) { /* blocking */
|
||||
mutex_lock((mutex_t)lock);
|
||||
success = TRUE;
|
||||
} else { /* non blocking */
|
||||
success = mutex_try_lock((mutex_t)lock);
|
||||
}
|
||||
dprintf(("PyThread_acquire_lock(%p, %d) -> %d\n", lock, waitflag, success));
|
||||
return success;
|
||||
dprintf(("PyThread_acquire_lock(%p, %d) called\n", lock, waitflag));
|
||||
if (waitflag) { /* blocking */
|
||||
mutex_lock((mutex_t)lock);
|
||||
success = TRUE;
|
||||
} else { /* non blocking */
|
||||
success = mutex_try_lock((mutex_t)lock);
|
||||
}
|
||||
dprintf(("PyThread_acquire_lock(%p, %d) -> %d\n", lock, waitflag, success));
|
||||
return success;
|
||||
}
|
||||
|
||||
void
|
||||
PyThread_release_lock(PyThread_type_lock lock)
|
||||
{
|
||||
dprintf(("PyThread_release_lock(%p) called\n", lock));
|
||||
mutex_unlock((mutex_t )lock);
|
||||
dprintf(("PyThread_release_lock(%p) called\n", lock));
|
||||
mutex_unlock((mutex_t )lock);
|
||||
}
|
||||
|
|
|
@ -13,28 +13,28 @@ PyThread__init_thread(void)
|
|||
long
|
||||
PyThread_start_new_thread(void (*func)(void *), void *arg)
|
||||
{
|
||||
int success = 0; /* init not needed when SOLARIS_THREADS and */
|
||||
/* C_THREADS implemented properly */
|
||||
int success = 0; /* init not needed when SOLARIS_THREADS and */
|
||||
/* C_THREADS implemented properly */
|
||||
|
||||
dprintf(("PyThread_start_new_thread called\n"));
|
||||
if (!initialized)
|
||||
PyThread_init_thread();
|
||||
return success < 0 ? -1 : 0;
|
||||
dprintf(("PyThread_start_new_thread called\n"));
|
||||
if (!initialized)
|
||||
PyThread_init_thread();
|
||||
return success < 0 ? -1 : 0;
|
||||
}
|
||||
|
||||
long
|
||||
PyThread_get_thread_ident(void)
|
||||
{
|
||||
if (!initialized)
|
||||
PyThread_init_thread();
|
||||
if (!initialized)
|
||||
PyThread_init_thread();
|
||||
}
|
||||
|
||||
void
|
||||
PyThread_exit_thread(void)
|
||||
{
|
||||
dprintf(("PyThread_exit_thread called\n"));
|
||||
if (!initialized)
|
||||
exit(0);
|
||||
dprintf(("PyThread_exit_thread called\n"));
|
||||
if (!initialized)
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -44,32 +44,32 @@ PyThread_type_lock
|
|||
PyThread_allocate_lock(void)
|
||||
{
|
||||
|
||||
dprintf(("PyThread_allocate_lock called\n"));
|
||||
if (!initialized)
|
||||
PyThread_init_thread();
|
||||
dprintf(("PyThread_allocate_lock called\n"));
|
||||
if (!initialized)
|
||||
PyThread_init_thread();
|
||||
|
||||
dprintf(("PyThread_allocate_lock() -> %p\n", lock));
|
||||
return (PyThread_type_lock) lock;
|
||||
dprintf(("PyThread_allocate_lock() -> %p\n", lock));
|
||||
return (PyThread_type_lock) lock;
|
||||
}
|
||||
|
||||
void
|
||||
PyThread_free_lock(PyThread_type_lock lock)
|
||||
{
|
||||
dprintf(("PyThread_free_lock(%p) called\n", lock));
|
||||
dprintf(("PyThread_free_lock(%p) called\n", lock));
|
||||
}
|
||||
|
||||
int
|
||||
PyThread_acquire_lock(PyThread_type_lock lock, int waitflag)
|
||||
{
|
||||
int success;
|
||||
int success;
|
||||
|
||||
dprintf(("PyThread_acquire_lock(%p, %d) called\n", lock, waitflag));
|
||||
dprintf(("PyThread_acquire_lock(%p, %d) -> %d\n", lock, waitflag, success));
|
||||
return success;
|
||||
dprintf(("PyThread_acquire_lock(%p, %d) called\n", lock, waitflag));
|
||||
dprintf(("PyThread_acquire_lock(%p, %d) -> %d\n", lock, waitflag, success));
|
||||
return success;
|
||||
}
|
||||
|
||||
void
|
||||
PyThread_release_lock(PyThread_type_lock lock)
|
||||
{
|
||||
dprintf(("PyThread_release_lock(%p) called\n", lock));
|
||||
dprintf(("PyThread_release_lock(%p) called\n", lock));
|
||||
}
|
||||
|
|
|
@ -3,13 +3,13 @@
|
|||
#include <lwp/lwp.h>
|
||||
#include <lwp/stackdep.h>
|
||||
|
||||
#define STACKSIZE 1000 /* stacksize for a thread */
|
||||
#define NSTACKS 2 /* # stacks to be put in cache initially */
|
||||
#define STACKSIZE 1000 /* stacksize for a thread */
|
||||
#define NSTACKS 2 /* # stacks to be put in cache initially */
|
||||
|
||||
struct lock {
|
||||
int lock_locked;
|
||||
cv_t lock_condvar;
|
||||
mon_t lock_monitor;
|
||||
int lock_locked;
|
||||
cv_t lock_condvar;
|
||||
mon_t lock_monitor;
|
||||
};
|
||||
|
||||
|
||||
|
@ -18,7 +18,7 @@ struct lock {
|
|||
*/
|
||||
static void PyThread__init_thread(void)
|
||||
{
|
||||
lwp_setstkcache(STACKSIZE, NSTACKS);
|
||||
lwp_setstkcache(STACKSIZE, NSTACKS);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -28,31 +28,31 @@ static void PyThread__init_thread(void)
|
|||
|
||||
long PyThread_start_new_thread(void (*func)(void *), void *arg)
|
||||
{
|
||||
thread_t tid;
|
||||
int success;
|
||||
dprintf(("PyThread_start_new_thread called\n"));
|
||||
if (!initialized)
|
||||
PyThread_init_thread();
|
||||
success = lwp_create(&tid, func, MINPRIO, 0, lwp_newstk(), 1, arg);
|
||||
return success < 0 ? -1 : 0;
|
||||
thread_t tid;
|
||||
int success;
|
||||
dprintf(("PyThread_start_new_thread called\n"));
|
||||
if (!initialized)
|
||||
PyThread_init_thread();
|
||||
success = lwp_create(&tid, func, MINPRIO, 0, lwp_newstk(), 1, arg);
|
||||
return success < 0 ? -1 : 0;
|
||||
}
|
||||
|
||||
long PyThread_get_thread_ident(void)
|
||||
{
|
||||
thread_t tid;
|
||||
if (!initialized)
|
||||
PyThread_init_thread();
|
||||
if (lwp_self(&tid) < 0)
|
||||
return -1;
|
||||
return tid.thread_id;
|
||||
thread_t tid;
|
||||
if (!initialized)
|
||||
PyThread_init_thread();
|
||||
if (lwp_self(&tid) < 0)
|
||||
return -1;
|
||||
return tid.thread_id;
|
||||
}
|
||||
|
||||
void PyThread_exit_thread(void)
|
||||
{
|
||||
dprintf(("PyThread_exit_thread called\n"));
|
||||
if (!initialized)
|
||||
exit(0);
|
||||
lwp_destroy(SELF);
|
||||
dprintf(("PyThread_exit_thread called\n"));
|
||||
if (!initialized)
|
||||
exit(0);
|
||||
lwp_destroy(SELF);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -60,54 +60,54 @@ void PyThread_exit_thread(void)
|
|||
*/
|
||||
PyThread_type_lock PyThread_allocate_lock(void)
|
||||
{
|
||||
struct lock *lock;
|
||||
extern char *malloc(size_t);
|
||||
struct lock *lock;
|
||||
extern char *malloc(size_t);
|
||||
|
||||
dprintf(("PyThread_allocate_lock called\n"));
|
||||
if (!initialized)
|
||||
PyThread_init_thread();
|
||||
dprintf(("PyThread_allocate_lock called\n"));
|
||||
if (!initialized)
|
||||
PyThread_init_thread();
|
||||
|
||||
lock = (struct lock *) malloc(sizeof(struct lock));
|
||||
lock->lock_locked = 0;
|
||||
(void) mon_create(&lock->lock_monitor);
|
||||
(void) cv_create(&lock->lock_condvar, lock->lock_monitor);
|
||||
dprintf(("PyThread_allocate_lock() -> %p\n", lock));
|
||||
return (PyThread_type_lock) lock;
|
||||
lock = (struct lock *) malloc(sizeof(struct lock));
|
||||
lock->lock_locked = 0;
|
||||
(void) mon_create(&lock->lock_monitor);
|
||||
(void) cv_create(&lock->lock_condvar, lock->lock_monitor);
|
||||
dprintf(("PyThread_allocate_lock() -> %p\n", lock));
|
||||
return (PyThread_type_lock) lock;
|
||||
}
|
||||
|
||||
void PyThread_free_lock(PyThread_type_lock lock)
|
||||
{
|
||||
dprintf(("PyThread_free_lock(%p) called\n", lock));
|
||||
mon_destroy(((struct lock *) lock)->lock_monitor);
|
||||
free((char *) lock);
|
||||
dprintf(("PyThread_free_lock(%p) called\n", lock));
|
||||
mon_destroy(((struct lock *) lock)->lock_monitor);
|
||||
free((char *) lock);
|
||||
}
|
||||
|
||||
int PyThread_acquire_lock(PyThread_type_lock lock, int waitflag)
|
||||
{
|
||||
int success;
|
||||
int success;
|
||||
|
||||
dprintf(("PyThread_acquire_lock(%p, %d) called\n", lock, waitflag));
|
||||
success = 0;
|
||||
dprintf(("PyThread_acquire_lock(%p, %d) called\n", lock, waitflag));
|
||||
success = 0;
|
||||
|
||||
(void) mon_enter(((struct lock *) lock)->lock_monitor);
|
||||
if (waitflag)
|
||||
while (((struct lock *) lock)->lock_locked)
|
||||
cv_wait(((struct lock *) lock)->lock_condvar);
|
||||
if (!((struct lock *) lock)->lock_locked) {
|
||||
success = 1;
|
||||
((struct lock *) lock)->lock_locked = 1;
|
||||
}
|
||||
cv_broadcast(((struct lock *) lock)->lock_condvar);
|
||||
mon_exit(((struct lock *) lock)->lock_monitor);
|
||||
dprintf(("PyThread_acquire_lock(%p, %d) -> %d\n", lock, waitflag, success));
|
||||
return success;
|
||||
(void) mon_enter(((struct lock *) lock)->lock_monitor);
|
||||
if (waitflag)
|
||||
while (((struct lock *) lock)->lock_locked)
|
||||
cv_wait(((struct lock *) lock)->lock_condvar);
|
||||
if (!((struct lock *) lock)->lock_locked) {
|
||||
success = 1;
|
||||
((struct lock *) lock)->lock_locked = 1;
|
||||
}
|
||||
cv_broadcast(((struct lock *) lock)->lock_condvar);
|
||||
mon_exit(((struct lock *) lock)->lock_monitor);
|
||||
dprintf(("PyThread_acquire_lock(%p, %d) -> %d\n", lock, waitflag, success));
|
||||
return success;
|
||||
}
|
||||
|
||||
void PyThread_release_lock(PyThread_type_lock lock)
|
||||
{
|
||||
dprintf(("PyThread_release_lock(%p) called\n", lock));
|
||||
(void) mon_enter(((struct lock *) lock)->lock_monitor);
|
||||
((struct lock *) lock)->lock_locked = 0;
|
||||
cv_broadcast(((struct lock *) lock)->lock_condvar);
|
||||
mon_exit(((struct lock *) lock)->lock_monitor);
|
||||
dprintf(("PyThread_release_lock(%p) called\n", lock));
|
||||
(void) mon_enter(((struct lock *) lock)->lock_monitor);
|
||||
((struct lock *) lock)->lock_locked = 0;
|
||||
cv_broadcast(((struct lock *) lock)->lock_condvar);
|
||||
mon_exit(((struct lock *) lock)->lock_monitor);
|
||||
}
|
||||
|
|
|
@ -10,81 +10,81 @@
|
|||
#endif
|
||||
|
||||
typedef struct NRMUTEX {
|
||||
LONG owned ;
|
||||
DWORD thread_id ;
|
||||
HANDLE hevent ;
|
||||
LONG owned ;
|
||||
DWORD thread_id ;
|
||||
HANDLE hevent ;
|
||||
} NRMUTEX, *PNRMUTEX ;
|
||||
|
||||
|
||||
BOOL
|
||||
InitializeNonRecursiveMutex(PNRMUTEX mutex)
|
||||
{
|
||||
mutex->owned = -1 ; /* No threads have entered NonRecursiveMutex */
|
||||
mutex->thread_id = 0 ;
|
||||
mutex->hevent = CreateEvent(NULL, FALSE, FALSE, NULL) ;
|
||||
return mutex->hevent != NULL ; /* TRUE if the mutex is created */
|
||||
mutex->owned = -1 ; /* No threads have entered NonRecursiveMutex */
|
||||
mutex->thread_id = 0 ;
|
||||
mutex->hevent = CreateEvent(NULL, FALSE, FALSE, NULL) ;
|
||||
return mutex->hevent != NULL ; /* TRUE if the mutex is created */
|
||||
}
|
||||
|
||||
VOID
|
||||
DeleteNonRecursiveMutex(PNRMUTEX mutex)
|
||||
{
|
||||
/* No in-use check */
|
||||
CloseHandle(mutex->hevent) ;
|
||||
mutex->hevent = NULL ; /* Just in case */
|
||||
/* No in-use check */
|
||||
CloseHandle(mutex->hevent) ;
|
||||
mutex->hevent = NULL ; /* Just in case */
|
||||
}
|
||||
|
||||
DWORD
|
||||
EnterNonRecursiveMutex(PNRMUTEX mutex, BOOL wait)
|
||||
{
|
||||
/* Assume that the thread waits successfully */
|
||||
DWORD ret ;
|
||||
/* Assume that the thread waits successfully */
|
||||
DWORD ret ;
|
||||
|
||||
/* InterlockedIncrement(&mutex->owned) == 0 means that no thread currently owns the mutex */
|
||||
if (!wait)
|
||||
{
|
||||
if (InterlockedCompareExchange(&mutex->owned, 0, -1) != -1)
|
||||
return WAIT_TIMEOUT ;
|
||||
ret = WAIT_OBJECT_0 ;
|
||||
}
|
||||
else
|
||||
ret = InterlockedIncrement(&mutex->owned) ?
|
||||
/* Some thread owns the mutex, let's wait... */
|
||||
WaitForSingleObject(mutex->hevent, INFINITE) : WAIT_OBJECT_0 ;
|
||||
/* InterlockedIncrement(&mutex->owned) == 0 means that no thread currently owns the mutex */
|
||||
if (!wait)
|
||||
{
|
||||
if (InterlockedCompareExchange(&mutex->owned, 0, -1) != -1)
|
||||
return WAIT_TIMEOUT ;
|
||||
ret = WAIT_OBJECT_0 ;
|
||||
}
|
||||
else
|
||||
ret = InterlockedIncrement(&mutex->owned) ?
|
||||
/* Some thread owns the mutex, let's wait... */
|
||||
WaitForSingleObject(mutex->hevent, INFINITE) : WAIT_OBJECT_0 ;
|
||||
|
||||
mutex->thread_id = GetCurrentThreadId() ; /* We own it */
|
||||
return ret ;
|
||||
mutex->thread_id = GetCurrentThreadId() ; /* We own it */
|
||||
return ret ;
|
||||
}
|
||||
|
||||
BOOL
|
||||
LeaveNonRecursiveMutex(PNRMUTEX mutex)
|
||||
{
|
||||
/* We don't own the mutex */
|
||||
mutex->thread_id = 0 ;
|
||||
return
|
||||
InterlockedDecrement(&mutex->owned) < 0 ||
|
||||
SetEvent(mutex->hevent) ; /* Other threads are waiting, wake one on them up */
|
||||
/* We don't own the mutex */
|
||||
mutex->thread_id = 0 ;
|
||||
return
|
||||
InterlockedDecrement(&mutex->owned) < 0 ||
|
||||
SetEvent(mutex->hevent) ; /* Other threads are waiting, wake one on them up */
|
||||
}
|
||||
|
||||
PNRMUTEX
|
||||
AllocNonRecursiveMutex(void)
|
||||
{
|
||||
PNRMUTEX mutex = (PNRMUTEX)malloc(sizeof(NRMUTEX)) ;
|
||||
if (mutex && !InitializeNonRecursiveMutex(mutex))
|
||||
{
|
||||
free(mutex) ;
|
||||
mutex = NULL ;
|
||||
}
|
||||
return mutex ;
|
||||
PNRMUTEX mutex = (PNRMUTEX)malloc(sizeof(NRMUTEX)) ;
|
||||
if (mutex && !InitializeNonRecursiveMutex(mutex))
|
||||
{
|
||||
free(mutex) ;
|
||||
mutex = NULL ;
|
||||
}
|
||||
return mutex ;
|
||||
}
|
||||
|
||||
void
|
||||
FreeNonRecursiveMutex(PNRMUTEX mutex)
|
||||
{
|
||||
if (mutex)
|
||||
{
|
||||
DeleteNonRecursiveMutex(mutex) ;
|
||||
free(mutex) ;
|
||||
}
|
||||
if (mutex)
|
||||
{
|
||||
DeleteNonRecursiveMutex(mutex) ;
|
||||
free(mutex) ;
|
||||
}
|
||||
}
|
||||
|
||||
long PyThread_get_thread_ident(void);
|
||||
|
@ -102,8 +102,8 @@ PyThread__init_thread(void)
|
|||
*/
|
||||
|
||||
typedef struct {
|
||||
void (*func)(void*);
|
||||
void *arg;
|
||||
void (*func)(void*);
|
||||
void *arg;
|
||||
} callobj;
|
||||
|
||||
/* thunker to call adapt between the function type used by the system's
|
||||
|
@ -115,66 +115,66 @@ static unsigned __stdcall
|
|||
#endif
|
||||
bootstrap(void *call)
|
||||
{
|
||||
callobj *obj = (callobj*)call;
|
||||
void (*func)(void*) = obj->func;
|
||||
void *arg = obj->arg;
|
||||
HeapFree(GetProcessHeap(), 0, obj);
|
||||
func(arg);
|
||||
return 0;
|
||||
callobj *obj = (callobj*)call;
|
||||
void (*func)(void*) = obj->func;
|
||||
void *arg = obj->arg;
|
||||
HeapFree(GetProcessHeap(), 0, obj);
|
||||
func(arg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
long
|
||||
PyThread_start_new_thread(void (*func)(void *), void *arg)
|
||||
{
|
||||
HANDLE hThread;
|
||||
unsigned threadID;
|
||||
callobj *obj;
|
||||
|
||||
dprintf(("%ld: PyThread_start_new_thread called\n",
|
||||
PyThread_get_thread_ident()));
|
||||
if (!initialized)
|
||||
PyThread_init_thread();
|
||||
HANDLE hThread;
|
||||
unsigned threadID;
|
||||
callobj *obj;
|
||||
|
||||
obj = (callobj*)HeapAlloc(GetProcessHeap(), 0, sizeof(*obj));
|
||||
if (!obj)
|
||||
return -1;
|
||||
obj->func = func;
|
||||
obj->arg = arg;
|
||||
dprintf(("%ld: PyThread_start_new_thread called\n",
|
||||
PyThread_get_thread_ident()));
|
||||
if (!initialized)
|
||||
PyThread_init_thread();
|
||||
|
||||
obj = (callobj*)HeapAlloc(GetProcessHeap(), 0, sizeof(*obj));
|
||||
if (!obj)
|
||||
return -1;
|
||||
obj->func = func;
|
||||
obj->arg = arg;
|
||||
#if defined(MS_WINCE)
|
||||
hThread = CreateThread(NULL,
|
||||
Py_SAFE_DOWNCAST(_pythread_stacksize, Py_ssize_t, SIZE_T),
|
||||
bootstrap, obj, 0, &threadID);
|
||||
hThread = CreateThread(NULL,
|
||||
Py_SAFE_DOWNCAST(_pythread_stacksize, Py_ssize_t, SIZE_T),
|
||||
bootstrap, obj, 0, &threadID);
|
||||
#else
|
||||
hThread = (HANDLE)_beginthreadex(0,
|
||||
Py_SAFE_DOWNCAST(_pythread_stacksize,
|
||||
Py_ssize_t, unsigned int),
|
||||
bootstrap, obj,
|
||||
0, &threadID);
|
||||
hThread = (HANDLE)_beginthreadex(0,
|
||||
Py_SAFE_DOWNCAST(_pythread_stacksize,
|
||||
Py_ssize_t, unsigned int),
|
||||
bootstrap, obj,
|
||||
0, &threadID);
|
||||
#endif
|
||||
if (hThread == 0) {
|
||||
if (hThread == 0) {
|
||||
#if defined(MS_WINCE)
|
||||
/* Save error in variable, to prevent PyThread_get_thread_ident
|
||||
from clobbering it. */
|
||||
unsigned e = GetLastError();
|
||||
dprintf(("%ld: PyThread_start_new_thread failed, win32 error code %u\n",
|
||||
PyThread_get_thread_ident(), e));
|
||||
/* Save error in variable, to prevent PyThread_get_thread_ident
|
||||
from clobbering it. */
|
||||
unsigned e = GetLastError();
|
||||
dprintf(("%ld: PyThread_start_new_thread failed, win32 error code %u\n",
|
||||
PyThread_get_thread_ident(), e));
|
||||
#else
|
||||
/* I've seen errno == EAGAIN here, which means "there are
|
||||
* too many threads".
|
||||
*/
|
||||
int e = errno;
|
||||
dprintf(("%ld: PyThread_start_new_thread failed, errno %d\n",
|
||||
PyThread_get_thread_ident(), e));
|
||||
/* I've seen errno == EAGAIN here, which means "there are
|
||||
* too many threads".
|
||||
*/
|
||||
int e = errno;
|
||||
dprintf(("%ld: PyThread_start_new_thread failed, errno %d\n",
|
||||
PyThread_get_thread_ident(), e));
|
||||
#endif
|
||||
threadID = (unsigned)-1;
|
||||
HeapFree(GetProcessHeap(), 0, obj);
|
||||
}
|
||||
else {
|
||||
dprintf(("%ld: PyThread_start_new_thread succeeded: %p\n",
|
||||
PyThread_get_thread_ident(), (void*)hThread));
|
||||
CloseHandle(hThread);
|
||||
}
|
||||
return (long) threadID;
|
||||
threadID = (unsigned)-1;
|
||||
HeapFree(GetProcessHeap(), 0, obj);
|
||||
}
|
||||
else {
|
||||
dprintf(("%ld: PyThread_start_new_thread succeeded: %p\n",
|
||||
PyThread_get_thread_ident(), (void*)hThread));
|
||||
CloseHandle(hThread);
|
||||
}
|
||||
return (long) threadID;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -184,22 +184,22 @@ PyThread_start_new_thread(void (*func)(void *), void *arg)
|
|||
long
|
||||
PyThread_get_thread_ident(void)
|
||||
{
|
||||
if (!initialized)
|
||||
PyThread_init_thread();
|
||||
if (!initialized)
|
||||
PyThread_init_thread();
|
||||
|
||||
return GetCurrentThreadId();
|
||||
return GetCurrentThreadId();
|
||||
}
|
||||
|
||||
void
|
||||
PyThread_exit_thread(void)
|
||||
{
|
||||
dprintf(("%ld: PyThread_exit_thread called\n", PyThread_get_thread_ident()));
|
||||
if (!initialized)
|
||||
exit(0);
|
||||
dprintf(("%ld: PyThread_exit_thread called\n", PyThread_get_thread_ident()));
|
||||
if (!initialized)
|
||||
exit(0);
|
||||
#if defined(MS_WINCE)
|
||||
ExitThread(0);
|
||||
ExitThread(0);
|
||||
#else
|
||||
_endthreadex(0);
|
||||
_endthreadex(0);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -211,25 +211,25 @@ PyThread_exit_thread(void)
|
|||
PyThread_type_lock
|
||||
PyThread_allocate_lock(void)
|
||||
{
|
||||
PNRMUTEX aLock;
|
||||
PNRMUTEX aLock;
|
||||
|
||||
dprintf(("PyThread_allocate_lock called\n"));
|
||||
if (!initialized)
|
||||
PyThread_init_thread();
|
||||
dprintf(("PyThread_allocate_lock called\n"));
|
||||
if (!initialized)
|
||||
PyThread_init_thread();
|
||||
|
||||
aLock = AllocNonRecursiveMutex() ;
|
||||
aLock = AllocNonRecursiveMutex() ;
|
||||
|
||||
dprintf(("%ld: PyThread_allocate_lock() -> %p\n", PyThread_get_thread_ident(), aLock));
|
||||
dprintf(("%ld: PyThread_allocate_lock() -> %p\n", PyThread_get_thread_ident(), aLock));
|
||||
|
||||
return (PyThread_type_lock) aLock;
|
||||
return (PyThread_type_lock) aLock;
|
||||
}
|
||||
|
||||
void
|
||||
PyThread_free_lock(PyThread_type_lock aLock)
|
||||
{
|
||||
dprintf(("%ld: PyThread_free_lock(%p) called\n", PyThread_get_thread_ident(),aLock));
|
||||
dprintf(("%ld: PyThread_free_lock(%p) called\n", PyThread_get_thread_ident(),aLock));
|
||||
|
||||
FreeNonRecursiveMutex(aLock) ;
|
||||
FreeNonRecursiveMutex(aLock) ;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -241,29 +241,29 @@ PyThread_free_lock(PyThread_type_lock aLock)
|
|||
int
|
||||
PyThread_acquire_lock(PyThread_type_lock aLock, int waitflag)
|
||||
{
|
||||
int success ;
|
||||
int success ;
|
||||
|
||||
dprintf(("%ld: PyThread_acquire_lock(%p, %d) called\n", PyThread_get_thread_ident(),aLock, waitflag));
|
||||
dprintf(("%ld: PyThread_acquire_lock(%p, %d) called\n", PyThread_get_thread_ident(),aLock, waitflag));
|
||||
|
||||
success = aLock && EnterNonRecursiveMutex((PNRMUTEX) aLock, (waitflag ? INFINITE : 0)) == WAIT_OBJECT_0 ;
|
||||
success = aLock && EnterNonRecursiveMutex((PNRMUTEX) aLock, (waitflag ? INFINITE : 0)) == WAIT_OBJECT_0 ;
|
||||
|
||||
dprintf(("%ld: PyThread_acquire_lock(%p, %d) -> %d\n", PyThread_get_thread_ident(),aLock, waitflag, success));
|
||||
dprintf(("%ld: PyThread_acquire_lock(%p, %d) -> %d\n", PyThread_get_thread_ident(),aLock, waitflag, success));
|
||||
|
||||
return success;
|
||||
return success;
|
||||
}
|
||||
|
||||
void
|
||||
PyThread_release_lock(PyThread_type_lock aLock)
|
||||
{
|
||||
dprintf(("%ld: PyThread_release_lock(%p) called\n", PyThread_get_thread_ident(),aLock));
|
||||
dprintf(("%ld: PyThread_release_lock(%p) called\n", PyThread_get_thread_ident(),aLock));
|
||||
|
||||
if (!(aLock && LeaveNonRecursiveMutex((PNRMUTEX) aLock)))
|
||||
dprintf(("%ld: Could not PyThread_release_lock(%p) error: %ld\n", PyThread_get_thread_ident(), aLock, GetLastError()));
|
||||
if (!(aLock && LeaveNonRecursiveMutex((PNRMUTEX) aLock)))
|
||||
dprintf(("%ld: Could not PyThread_release_lock(%p) error: %ld\n", PyThread_get_thread_ident(), aLock, GetLastError()));
|
||||
}
|
||||
|
||||
/* minimum/maximum thread stack sizes supported */
|
||||
#define THREAD_MIN_STACKSIZE 0x8000 /* 32kB */
|
||||
#define THREAD_MAX_STACKSIZE 0x10000000 /* 256MB */
|
||||
#define THREAD_MIN_STACKSIZE 0x8000 /* 32kB */
|
||||
#define THREAD_MAX_STACKSIZE 0x10000000 /* 256MB */
|
||||
|
||||
/* set the thread stack size.
|
||||
* Return 0 if size is valid, -1 otherwise.
|
||||
|
@ -271,22 +271,22 @@ PyThread_release_lock(PyThread_type_lock aLock)
|
|||
static int
|
||||
_pythread_nt_set_stacksize(size_t size)
|
||||
{
|
||||
/* set to default */
|
||||
if (size == 0) {
|
||||
_pythread_stacksize = 0;
|
||||
return 0;
|
||||
}
|
||||
/* set to default */
|
||||
if (size == 0) {
|
||||
_pythread_stacksize = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* valid range? */
|
||||
if (size >= THREAD_MIN_STACKSIZE && size < THREAD_MAX_STACKSIZE) {
|
||||
_pythread_stacksize = size;
|
||||
return 0;
|
||||
}
|
||||
/* valid range? */
|
||||
if (size >= THREAD_MIN_STACKSIZE && size < THREAD_MAX_STACKSIZE) {
|
||||
_pythread_stacksize = size;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
#define THREAD_SET_STACKSIZE(x) _pythread_nt_set_stacksize(x)
|
||||
#define THREAD_SET_STACKSIZE(x) _pythread_nt_set_stacksize(x)
|
||||
|
||||
|
||||
/* use native Windows TLS functions */
|
||||
|
@ -296,13 +296,13 @@ _pythread_nt_set_stacksize(size_t size)
|
|||
int
|
||||
PyThread_create_key(void)
|
||||
{
|
||||
return (int) TlsAlloc();
|
||||
return (int) TlsAlloc();
|
||||
}
|
||||
|
||||
void
|
||||
PyThread_delete_key(int key)
|
||||
{
|
||||
TlsFree(key);
|
||||
TlsFree(key);
|
||||
}
|
||||
|
||||
/* We must be careful to emulate the strange semantics implemented in thread.c,
|
||||
|
@ -311,42 +311,42 @@ PyThread_delete_key(int key)
|
|||
int
|
||||
PyThread_set_key_value(int key, void *value)
|
||||
{
|
||||
BOOL ok;
|
||||
void *oldvalue;
|
||||
BOOL ok;
|
||||
void *oldvalue;
|
||||
|
||||
assert(value != NULL);
|
||||
oldvalue = TlsGetValue(key);
|
||||
if (oldvalue != NULL)
|
||||
/* ignore value if already set */
|
||||
return 0;
|
||||
ok = TlsSetValue(key, value);
|
||||
if (!ok)
|
||||
return -1;
|
||||
return 0;
|
||||
assert(value != NULL);
|
||||
oldvalue = TlsGetValue(key);
|
||||
if (oldvalue != NULL)
|
||||
/* ignore value if already set */
|
||||
return 0;
|
||||
ok = TlsSetValue(key, value);
|
||||
if (!ok)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void *
|
||||
PyThread_get_key_value(int key)
|
||||
{
|
||||
/* because TLS is used in the Py_END_ALLOW_THREAD macro,
|
||||
* it is necessary to preserve the windows error state, because
|
||||
* it is assumed to be preserved across the call to the macro.
|
||||
* Ideally, the macro should be fixed, but it is simpler to
|
||||
* do it here.
|
||||
*/
|
||||
DWORD error = GetLastError();
|
||||
void *result = TlsGetValue(key);
|
||||
SetLastError(error);
|
||||
return result;
|
||||
/* because TLS is used in the Py_END_ALLOW_THREAD macro,
|
||||
* it is necessary to preserve the windows error state, because
|
||||
* it is assumed to be preserved across the call to the macro.
|
||||
* Ideally, the macro should be fixed, but it is simpler to
|
||||
* do it here.
|
||||
*/
|
||||
DWORD error = GetLastError();
|
||||
void *result = TlsGetValue(key);
|
||||
SetLastError(error);
|
||||
return result;
|
||||
}
|
||||
|
||||
void
|
||||
PyThread_delete_key_value(int key)
|
||||
{
|
||||
/* NULL is used as "key missing", and it is also the default
|
||||
* given by TlsGetValue() if nothing has been set yet.
|
||||
*/
|
||||
TlsSetValue(key, NULL);
|
||||
/* NULL is used as "key missing", and it is also the default
|
||||
* given by TlsGetValue() if nothing has been set yet.
|
||||
*/
|
||||
TlsSetValue(key, NULL);
|
||||
}
|
||||
|
||||
/* reinitialization of TLS is not necessary after fork when using
|
||||
|
|
|
@ -16,10 +16,10 @@ long PyThread_get_thread_ident(void);
|
|||
|
||||
/* default thread stack size of 64kB */
|
||||
#if !defined(THREAD_STACK_SIZE)
|
||||
#define THREAD_STACK_SIZE 0x10000
|
||||
#define THREAD_STACK_SIZE 0x10000
|
||||
#endif
|
||||
|
||||
#define OS2_STACKSIZE(x) (x ? x : THREAD_STACK_SIZE)
|
||||
#define OS2_STACKSIZE(x) (x ? x : THREAD_STACK_SIZE)
|
||||
|
||||
/*
|
||||
* Initialization of the C package, should not be needed.
|
||||
|
@ -35,113 +35,113 @@ PyThread__init_thread(void)
|
|||
long
|
||||
PyThread_start_new_thread(void (*func)(void *), void *arg)
|
||||
{
|
||||
int thread_id;
|
||||
int thread_id;
|
||||
|
||||
thread_id = _beginthread(func,
|
||||
NULL,
|
||||
OS2_STACKSIZE(_pythread_stacksize),
|
||||
arg);
|
||||
thread_id = _beginthread(func,
|
||||
NULL,
|
||||
OS2_STACKSIZE(_pythread_stacksize),
|
||||
arg);
|
||||
|
||||
if (thread_id == -1) {
|
||||
dprintf(("_beginthread failed. return %ld\n", errno));
|
||||
}
|
||||
if (thread_id == -1) {
|
||||
dprintf(("_beginthread failed. return %ld\n", errno));
|
||||
}
|
||||
|
||||
return thread_id;
|
||||
return thread_id;
|
||||
}
|
||||
|
||||
long
|
||||
PyThread_get_thread_ident(void)
|
||||
{
|
||||
#if !defined(PYCC_GCC)
|
||||
PPIB pib;
|
||||
PTIB tib;
|
||||
PPIB pib;
|
||||
PTIB tib;
|
||||
#endif
|
||||
|
||||
if (!initialized)
|
||||
PyThread_init_thread();
|
||||
if (!initialized)
|
||||
PyThread_init_thread();
|
||||
|
||||
#if defined(PYCC_GCC)
|
||||
return _gettid();
|
||||
return _gettid();
|
||||
#else
|
||||
DosGetInfoBlocks(&tib, &pib);
|
||||
return tib->tib_ptib2->tib2_ultid;
|
||||
DosGetInfoBlocks(&tib, &pib);
|
||||
return tib->tib_ptib2->tib2_ultid;
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
PyThread_exit_thread(void)
|
||||
{
|
||||
dprintf(("%ld: PyThread_exit_thread called\n",
|
||||
PyThread_get_thread_ident()));
|
||||
if (!initialized)
|
||||
exit(0);
|
||||
_endthread();
|
||||
dprintf(("%ld: PyThread_exit_thread called\n",
|
||||
PyThread_get_thread_ident()));
|
||||
if (!initialized)
|
||||
exit(0);
|
||||
_endthread();
|
||||
}
|
||||
|
||||
/*
|
||||
* Lock support. This is implemented with an event semaphore and critical
|
||||
* sections to make it behave more like a posix mutex than its OS/2
|
||||
* sections to make it behave more like a posix mutex than its OS/2
|
||||
* counterparts.
|
||||
*/
|
||||
|
||||
typedef struct os2_lock_t {
|
||||
int is_set;
|
||||
HEV changed;
|
||||
int is_set;
|
||||
HEV changed;
|
||||
} *type_os2_lock;
|
||||
|
||||
PyThread_type_lock
|
||||
PyThread_type_lock
|
||||
PyThread_allocate_lock(void)
|
||||
{
|
||||
#if defined(PYCC_GCC)
|
||||
_fmutex *sem = malloc(sizeof(_fmutex));
|
||||
if (!initialized)
|
||||
PyThread_init_thread();
|
||||
dprintf(("%ld: PyThread_allocate_lock() -> %lx\n",
|
||||
PyThread_get_thread_ident(),
|
||||
(long)sem));
|
||||
if (_fmutex_create(sem, 0)) {
|
||||
free(sem);
|
||||
sem = NULL;
|
||||
}
|
||||
return (PyThread_type_lock)sem;
|
||||
_fmutex *sem = malloc(sizeof(_fmutex));
|
||||
if (!initialized)
|
||||
PyThread_init_thread();
|
||||
dprintf(("%ld: PyThread_allocate_lock() -> %lx\n",
|
||||
PyThread_get_thread_ident(),
|
||||
(long)sem));
|
||||
if (_fmutex_create(sem, 0)) {
|
||||
free(sem);
|
||||
sem = NULL;
|
||||
}
|
||||
return (PyThread_type_lock)sem;
|
||||
#else
|
||||
APIRET rc;
|
||||
type_os2_lock lock = (type_os2_lock)malloc(sizeof(struct os2_lock_t));
|
||||
APIRET rc;
|
||||
type_os2_lock lock = (type_os2_lock)malloc(sizeof(struct os2_lock_t));
|
||||
|
||||
dprintf(("PyThread_allocate_lock called\n"));
|
||||
if (!initialized)
|
||||
PyThread_init_thread();
|
||||
dprintf(("PyThread_allocate_lock called\n"));
|
||||
if (!initialized)
|
||||
PyThread_init_thread();
|
||||
|
||||
lock->is_set = 0;
|
||||
lock->is_set = 0;
|
||||
|
||||
DosCreateEventSem(NULL, &lock->changed, 0, 0);
|
||||
DosCreateEventSem(NULL, &lock->changed, 0, 0);
|
||||
|
||||
dprintf(("%ld: PyThread_allocate_lock() -> %p\n",
|
||||
PyThread_get_thread_ident(),
|
||||
lock->changed));
|
||||
dprintf(("%ld: PyThread_allocate_lock() -> %p\n",
|
||||
PyThread_get_thread_ident(),
|
||||
lock->changed));
|
||||
|
||||
return (PyThread_type_lock)lock;
|
||||
return (PyThread_type_lock)lock;
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
PyThread_free_lock(PyThread_type_lock aLock)
|
||||
{
|
||||
#if !defined(PYCC_GCC)
|
||||
type_os2_lock lock = (type_os2_lock)aLock;
|
||||
type_os2_lock lock = (type_os2_lock)aLock;
|
||||
#endif
|
||||
|
||||
dprintf(("%ld: PyThread_free_lock(%p) called\n",
|
||||
PyThread_get_thread_ident(),aLock));
|
||||
dprintf(("%ld: PyThread_free_lock(%p) called\n",
|
||||
PyThread_get_thread_ident(),aLock));
|
||||
|
||||
#if defined(PYCC_GCC)
|
||||
if (aLock) {
|
||||
_fmutex_close((_fmutex *)aLock);
|
||||
free((_fmutex *)aLock);
|
||||
}
|
||||
if (aLock) {
|
||||
_fmutex_close((_fmutex *)aLock);
|
||||
free((_fmutex *)aLock);
|
||||
}
|
||||
#else
|
||||
DosCloseEventSem(lock->changed);
|
||||
free(aLock);
|
||||
DosCloseEventSem(lock->changed);
|
||||
free(aLock);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -150,98 +150,98 @@ PyThread_free_lock(PyThread_type_lock aLock)
|
|||
*
|
||||
* and 0 if the lock was not acquired.
|
||||
*/
|
||||
int
|
||||
int
|
||||
PyThread_acquire_lock(PyThread_type_lock aLock, int waitflag)
|
||||
{
|
||||
#if !defined(PYCC_GCC)
|
||||
int done = 0;
|
||||
ULONG count;
|
||||
PID pid = 0;
|
||||
TID tid = 0;
|
||||
type_os2_lock lock = (type_os2_lock)aLock;
|
||||
int done = 0;
|
||||
ULONG count;
|
||||
PID pid = 0;
|
||||
TID tid = 0;
|
||||
type_os2_lock lock = (type_os2_lock)aLock;
|
||||
#endif
|
||||
|
||||
dprintf(("%ld: PyThread_acquire_lock(%p, %d) called\n",
|
||||
PyThread_get_thread_ident(),
|
||||
aLock,
|
||||
waitflag));
|
||||
dprintf(("%ld: PyThread_acquire_lock(%p, %d) called\n",
|
||||
PyThread_get_thread_ident(),
|
||||
aLock,
|
||||
waitflag));
|
||||
|
||||
#if defined(PYCC_GCC)
|
||||
/* always successful if the lock doesn't exist */
|
||||
if (aLock &&
|
||||
_fmutex_request((_fmutex *)aLock, waitflag ? 0 : _FMR_NOWAIT))
|
||||
return 0;
|
||||
/* always successful if the lock doesn't exist */
|
||||
if (aLock &&
|
||||
_fmutex_request((_fmutex *)aLock, waitflag ? 0 : _FMR_NOWAIT))
|
||||
return 0;
|
||||
#else
|
||||
while (!done) {
|
||||
/* if the lock is currently set, we have to wait for
|
||||
* the state to change
|
||||
*/
|
||||
if (lock->is_set) {
|
||||
if (!waitflag)
|
||||
return 0;
|
||||
DosWaitEventSem(lock->changed, SEM_INDEFINITE_WAIT);
|
||||
}
|
||||
while (!done) {
|
||||
/* if the lock is currently set, we have to wait for
|
||||
* the state to change
|
||||
*/
|
||||
if (lock->is_set) {
|
||||
if (!waitflag)
|
||||
return 0;
|
||||
DosWaitEventSem(lock->changed, SEM_INDEFINITE_WAIT);
|
||||
}
|
||||
|
||||
/* enter a critical section and try to get the semaphore. If
|
||||
* it is still locked, we will try again.
|
||||
*/
|
||||
if (DosEnterCritSec())
|
||||
return 0;
|
||||
/* enter a critical section and try to get the semaphore. If
|
||||
* it is still locked, we will try again.
|
||||
*/
|
||||
if (DosEnterCritSec())
|
||||
return 0;
|
||||
|
||||
if (!lock->is_set) {
|
||||
lock->is_set = 1;
|
||||
DosResetEventSem(lock->changed, &count);
|
||||
done = 1;
|
||||
}
|
||||
if (!lock->is_set) {
|
||||
lock->is_set = 1;
|
||||
DosResetEventSem(lock->changed, &count);
|
||||
done = 1;
|
||||
}
|
||||
|
||||
DosExitCritSec();
|
||||
}
|
||||
DosExitCritSec();
|
||||
}
|
||||
#endif
|
||||
|
||||
return 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
PyThread_release_lock(PyThread_type_lock aLock)
|
||||
{
|
||||
#if !defined(PYCC_GCC)
|
||||
type_os2_lock lock = (type_os2_lock)aLock;
|
||||
type_os2_lock lock = (type_os2_lock)aLock;
|
||||
#endif
|
||||
|
||||
dprintf(("%ld: PyThread_release_lock(%p) called\n",
|
||||
PyThread_get_thread_ident(),
|
||||
aLock));
|
||||
dprintf(("%ld: PyThread_release_lock(%p) called\n",
|
||||
PyThread_get_thread_ident(),
|
||||
aLock));
|
||||
|
||||
#if defined(PYCC_GCC)
|
||||
if (aLock)
|
||||
_fmutex_release((_fmutex *)aLock);
|
||||
if (aLock)
|
||||
_fmutex_release((_fmutex *)aLock);
|
||||
#else
|
||||
if (!lock->is_set) {
|
||||
dprintf(("%ld: Could not PyThread_release_lock(%p) error: %l\n",
|
||||
PyThread_get_thread_ident(),
|
||||
aLock,
|
||||
GetLastError()));
|
||||
return;
|
||||
}
|
||||
if (!lock->is_set) {
|
||||
dprintf(("%ld: Could not PyThread_release_lock(%p) error: %l\n",
|
||||
PyThread_get_thread_ident(),
|
||||
aLock,
|
||||
GetLastError()));
|
||||
return;
|
||||
}
|
||||
|
||||
if (DosEnterCritSec()) {
|
||||
dprintf(("%ld: Could not PyThread_release_lock(%p) error: %l\n",
|
||||
PyThread_get_thread_ident(),
|
||||
aLock,
|
||||
GetLastError()));
|
||||
return;
|
||||
}
|
||||
if (DosEnterCritSec()) {
|
||||
dprintf(("%ld: Could not PyThread_release_lock(%p) error: %l\n",
|
||||
PyThread_get_thread_ident(),
|
||||
aLock,
|
||||
GetLastError()));
|
||||
return;
|
||||
}
|
||||
|
||||
lock->is_set = 0;
|
||||
DosPostEventSem(lock->changed);
|
||||
lock->is_set = 0;
|
||||
DosPostEventSem(lock->changed);
|
||||
|
||||
DosExitCritSec();
|
||||
DosExitCritSec();
|
||||
#endif
|
||||
}
|
||||
|
||||
/* minimum/maximum thread stack sizes supported */
|
||||
#define THREAD_MIN_STACKSIZE 0x8000 /* 32kB */
|
||||
#define THREAD_MAX_STACKSIZE 0x2000000 /* 32MB */
|
||||
#define THREAD_MIN_STACKSIZE 0x8000 /* 32kB */
|
||||
#define THREAD_MAX_STACKSIZE 0x2000000 /* 32MB */
|
||||
|
||||
/* set the thread stack size.
|
||||
* Return 0 if size is valid, -1 otherwise.
|
||||
|
@ -249,19 +249,19 @@ PyThread_release_lock(PyThread_type_lock aLock)
|
|||
static int
|
||||
_pythread_os2_set_stacksize(size_t size)
|
||||
{
|
||||
/* set to default */
|
||||
if (size == 0) {
|
||||
_pythread_stacksize = 0;
|
||||
return 0;
|
||||
}
|
||||
/* set to default */
|
||||
if (size == 0) {
|
||||
_pythread_stacksize = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* valid range? */
|
||||
if (size >= THREAD_MIN_STACKSIZE && size < THREAD_MAX_STACKSIZE) {
|
||||
_pythread_stacksize = size;
|
||||
return 0;
|
||||
}
|
||||
/* valid range? */
|
||||
if (size >= THREAD_MIN_STACKSIZE && size < THREAD_MAX_STACKSIZE) {
|
||||
_pythread_stacksize = size;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
#define THREAD_SET_STACKSIZE(x) _pythread_os2_set_stacksize(x)
|
||||
#define THREAD_SET_STACKSIZE(x) _pythread_os2_set_stacksize(x)
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
http://www.gnu.org/software/pth
|
||||
2000-05-03 Andy Dustman <andy@dustman.net>
|
||||
|
||||
Adapted from Posix threads interface
|
||||
Adapted from Posix threads interface
|
||||
12 May 1997 -- david arnold <davida@pobox.com>
|
||||
*/
|
||||
|
||||
|
@ -22,10 +22,10 @@
|
|||
*/
|
||||
|
||||
typedef struct {
|
||||
char locked; /* 0=unlocked, 1=locked */
|
||||
/* a <cond, mutex> pair to handle an acquire of a locked lock */
|
||||
pth_cond_t lock_released;
|
||||
pth_mutex_t mut;
|
||||
char locked; /* 0=unlocked, 1=locked */
|
||||
/* a <cond, mutex> pair to handle an acquire of a locked lock */
|
||||
pth_cond_t lock_released;
|
||||
pth_mutex_t mut;
|
||||
} pth_lock;
|
||||
|
||||
#define CHECK_STATUS(name) if (status == -1) { printf("%d ", status); perror(name); error = 1; }
|
||||
|
@ -38,10 +38,10 @@ pth_attr_t PyThread_attr;
|
|||
|
||||
static void PyThread__init_thread(void)
|
||||
{
|
||||
pth_init();
|
||||
PyThread_attr = pth_attr_new();
|
||||
pth_attr_set(PyThread_attr, PTH_ATTR_STACK_SIZE, 1<<18);
|
||||
pth_attr_set(PyThread_attr, PTH_ATTR_JOINABLE, FALSE);
|
||||
pth_init();
|
||||
PyThread_attr = pth_attr_new();
|
||||
pth_attr_set(PyThread_attr, PTH_ATTR_STACK_SIZE, 1<<18);
|
||||
pth_attr_set(PyThread_attr, PTH_ATTR_JOINABLE, FALSE);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -51,35 +51,35 @@ static void PyThread__init_thread(void)
|
|||
|
||||
long PyThread_start_new_thread(void (*func)(void *), void *arg)
|
||||
{
|
||||
pth_t th;
|
||||
dprintf(("PyThread_start_new_thread called\n"));
|
||||
if (!initialized)
|
||||
PyThread_init_thread();
|
||||
pth_t th;
|
||||
dprintf(("PyThread_start_new_thread called\n"));
|
||||
if (!initialized)
|
||||
PyThread_init_thread();
|
||||
|
||||
th = pth_spawn(PyThread_attr,
|
||||
(void* (*)(void *))func,
|
||||
(void *)arg
|
||||
);
|
||||
th = pth_spawn(PyThread_attr,
|
||||
(void* (*)(void *))func,
|
||||
(void *)arg
|
||||
);
|
||||
|
||||
return th;
|
||||
return th;
|
||||
}
|
||||
|
||||
long PyThread_get_thread_ident(void)
|
||||
{
|
||||
volatile pth_t threadid;
|
||||
if (!initialized)
|
||||
PyThread_init_thread();
|
||||
/* Jump through some hoops for Alpha OSF/1 */
|
||||
threadid = pth_self();
|
||||
return (long) *(long *) &threadid;
|
||||
volatile pth_t threadid;
|
||||
if (!initialized)
|
||||
PyThread_init_thread();
|
||||
/* Jump through some hoops for Alpha OSF/1 */
|
||||
threadid = pth_self();
|
||||
return (long) *(long *) &threadid;
|
||||
}
|
||||
|
||||
void PyThread_exit_thread(void)
|
||||
{
|
||||
dprintf(("PyThread_exit_thread called\n"));
|
||||
if (!initialized) {
|
||||
exit(0);
|
||||
}
|
||||
dprintf(("PyThread_exit_thread called\n"));
|
||||
if (!initialized) {
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -87,92 +87,92 @@ void PyThread_exit_thread(void)
|
|||
*/
|
||||
PyThread_type_lock PyThread_allocate_lock(void)
|
||||
{
|
||||
pth_lock *lock;
|
||||
int status, error = 0;
|
||||
pth_lock *lock;
|
||||
int status, error = 0;
|
||||
|
||||
dprintf(("PyThread_allocate_lock called\n"));
|
||||
if (!initialized)
|
||||
PyThread_init_thread();
|
||||
dprintf(("PyThread_allocate_lock called\n"));
|
||||
if (!initialized)
|
||||
PyThread_init_thread();
|
||||
|
||||
lock = (pth_lock *) malloc(sizeof(pth_lock));
|
||||
memset((void *)lock, '\0', sizeof(pth_lock));
|
||||
if (lock) {
|
||||
lock->locked = 0;
|
||||
status = pth_mutex_init(&lock->mut);
|
||||
CHECK_STATUS("pth_mutex_init");
|
||||
status = pth_cond_init(&lock->lock_released);
|
||||
CHECK_STATUS("pth_cond_init");
|
||||
if (error) {
|
||||
free((void *)lock);
|
||||
lock = NULL;
|
||||
}
|
||||
}
|
||||
dprintf(("PyThread_allocate_lock() -> %p\n", lock));
|
||||
return (PyThread_type_lock) lock;
|
||||
lock = (pth_lock *) malloc(sizeof(pth_lock));
|
||||
memset((void *)lock, '\0', sizeof(pth_lock));
|
||||
if (lock) {
|
||||
lock->locked = 0;
|
||||
status = pth_mutex_init(&lock->mut);
|
||||
CHECK_STATUS("pth_mutex_init");
|
||||
status = pth_cond_init(&lock->lock_released);
|
||||
CHECK_STATUS("pth_cond_init");
|
||||
if (error) {
|
||||
free((void *)lock);
|
||||
lock = NULL;
|
||||
}
|
||||
}
|
||||
dprintf(("PyThread_allocate_lock() -> %p\n", lock));
|
||||
return (PyThread_type_lock) lock;
|
||||
}
|
||||
|
||||
void PyThread_free_lock(PyThread_type_lock lock)
|
||||
{
|
||||
pth_lock *thelock = (pth_lock *)lock;
|
||||
pth_lock *thelock = (pth_lock *)lock;
|
||||
|
||||
dprintf(("PyThread_free_lock(%p) called\n", lock));
|
||||
dprintf(("PyThread_free_lock(%p) called\n", lock));
|
||||
|
||||
free((void *)thelock);
|
||||
free((void *)thelock);
|
||||
}
|
||||
|
||||
int PyThread_acquire_lock(PyThread_type_lock lock, int waitflag)
|
||||
{
|
||||
int success;
|
||||
pth_lock *thelock = (pth_lock *)lock;
|
||||
int status, error = 0;
|
||||
int success;
|
||||
pth_lock *thelock = (pth_lock *)lock;
|
||||
int status, error = 0;
|
||||
|
||||
dprintf(("PyThread_acquire_lock(%p, %d) called\n", lock, waitflag));
|
||||
dprintf(("PyThread_acquire_lock(%p, %d) called\n", lock, waitflag));
|
||||
|
||||
status = pth_mutex_acquire(&thelock->mut, !waitflag, NULL);
|
||||
CHECK_STATUS("pth_mutex_acquire[1]");
|
||||
success = thelock->locked == 0;
|
||||
if (success) thelock->locked = 1;
|
||||
status = pth_mutex_release( &thelock->mut );
|
||||
CHECK_STATUS("pth_mutex_release[1]");
|
||||
status = pth_mutex_acquire(&thelock->mut, !waitflag, NULL);
|
||||
CHECK_STATUS("pth_mutex_acquire[1]");
|
||||
success = thelock->locked == 0;
|
||||
if (success) thelock->locked = 1;
|
||||
status = pth_mutex_release( &thelock->mut );
|
||||
CHECK_STATUS("pth_mutex_release[1]");
|
||||
|
||||
if ( !success && waitflag ) {
|
||||
/* continue trying until we get the lock */
|
||||
if ( !success && waitflag ) {
|
||||
/* continue trying until we get the lock */
|
||||
|
||||
/* mut must be locked by me -- part of the condition
|
||||
* protocol */
|
||||
status = pth_mutex_acquire( &thelock->mut, !waitflag, NULL );
|
||||
CHECK_STATUS("pth_mutex_acquire[2]");
|
||||
while ( thelock->locked ) {
|
||||
status = pth_cond_await(&thelock->lock_released,
|
||||
&thelock->mut, NULL);
|
||||
CHECK_STATUS("pth_cond_await");
|
||||
}
|
||||
thelock->locked = 1;
|
||||
status = pth_mutex_release( &thelock->mut );
|
||||
CHECK_STATUS("pth_mutex_release[2]");
|
||||
success = 1;
|
||||
/* mut must be locked by me -- part of the condition
|
||||
* protocol */
|
||||
status = pth_mutex_acquire( &thelock->mut, !waitflag, NULL );
|
||||
CHECK_STATUS("pth_mutex_acquire[2]");
|
||||
while ( thelock->locked ) {
|
||||
status = pth_cond_await(&thelock->lock_released,
|
||||
&thelock->mut, NULL);
|
||||
CHECK_STATUS("pth_cond_await");
|
||||
}
|
||||
if (error) success = 0;
|
||||
dprintf(("PyThread_acquire_lock(%p, %d) -> %d\n", lock, waitflag, success));
|
||||
return success;
|
||||
thelock->locked = 1;
|
||||
status = pth_mutex_release( &thelock->mut );
|
||||
CHECK_STATUS("pth_mutex_release[2]");
|
||||
success = 1;
|
||||
}
|
||||
if (error) success = 0;
|
||||
dprintf(("PyThread_acquire_lock(%p, %d) -> %d\n", lock, waitflag, success));
|
||||
return success;
|
||||
}
|
||||
|
||||
void PyThread_release_lock(PyThread_type_lock lock)
|
||||
{
|
||||
pth_lock *thelock = (pth_lock *)lock;
|
||||
int status, error = 0;
|
||||
pth_lock *thelock = (pth_lock *)lock;
|
||||
int status, error = 0;
|
||||
|
||||
dprintf(("PyThread_release_lock(%p) called\n", lock));
|
||||
dprintf(("PyThread_release_lock(%p) called\n", lock));
|
||||
|
||||
status = pth_mutex_acquire( &thelock->mut, 0, NULL );
|
||||
CHECK_STATUS("pth_mutex_acquire[3]");
|
||||
status = pth_mutex_acquire( &thelock->mut, 0, NULL );
|
||||
CHECK_STATUS("pth_mutex_acquire[3]");
|
||||
|
||||
thelock->locked = 0;
|
||||
thelock->locked = 0;
|
||||
|
||||
status = pth_mutex_release( &thelock->mut );
|
||||
CHECK_STATUS("pth_mutex_release[3]");
|
||||
status = pth_mutex_release( &thelock->mut );
|
||||
CHECK_STATUS("pth_mutex_release[3]");
|
||||
|
||||
/* wake up someone (anyone, if any) waiting on the lock */
|
||||
status = pth_cond_notify( &thelock->lock_released, 0 );
|
||||
CHECK_STATUS("pth_cond_notify");
|
||||
/* wake up someone (anyone, if any) waiting on the lock */
|
||||
status = pth_cond_notify( &thelock->lock_released, 0 );
|
||||
CHECK_STATUS("pth_cond_notify");
|
||||
}
|
||||
|
|
|
@ -16,10 +16,10 @@
|
|||
be conditional on _POSIX_THREAD_ATTR_STACKSIZE being defined. */
|
||||
#ifdef _POSIX_THREAD_ATTR_STACKSIZE
|
||||
#ifndef THREAD_STACK_SIZE
|
||||
#define THREAD_STACK_SIZE 0 /* use default stack size */
|
||||
#define THREAD_STACK_SIZE 0 /* use default stack size */
|
||||
#endif
|
||||
/* for safety, ensure a viable minimum stacksize */
|
||||
#define THREAD_STACK_MIN 0x8000 /* 32kB */
|
||||
#define THREAD_STACK_MIN 0x8000 /* 32kB */
|
||||
#else /* !_POSIX_THREAD_ATTR_STACKSIZE */
|
||||
#ifdef THREAD_STACK_SIZE
|
||||
#error "THREAD_STACK_SIZE defined but _POSIX_THREAD_ATTR_STACKSIZE undefined"
|
||||
|
@ -28,9 +28,9 @@
|
|||
|
||||
/* The POSIX spec says that implementations supporting the sem_*
|
||||
family of functions must indicate this by defining
|
||||
_POSIX_SEMAPHORES. */
|
||||
_POSIX_SEMAPHORES. */
|
||||
#ifdef _POSIX_SEMAPHORES
|
||||
/* On FreeBSD 4.x, _POSIX_SEMAPHORES is defined empty, so
|
||||
/* On FreeBSD 4.x, _POSIX_SEMAPHORES is defined empty, so
|
||||
we need to add 0 to make it work there as well. */
|
||||
#if (_POSIX_SEMAPHORES+0) == -1
|
||||
#define HAVE_BROKEN_POSIX_SEMAPHORES
|
||||
|
@ -99,10 +99,10 @@
|
|||
*/
|
||||
|
||||
typedef struct {
|
||||
char locked; /* 0=unlocked, 1=locked */
|
||||
/* a <cond, mutex> pair to handle an acquire of a locked lock */
|
||||
pthread_cond_t lock_released;
|
||||
pthread_mutex_t mut;
|
||||
char locked; /* 0=unlocked, 1=locked */
|
||||
/* a <cond, mutex> pair to handle an acquire of a locked lock */
|
||||
pthread_cond_t lock_released;
|
||||
pthread_mutex_t mut;
|
||||
} pthread_lock;
|
||||
|
||||
#define CHECK_STATUS(name) if (status != 0) { perror(name); error = 1; }
|
||||
|
@ -120,11 +120,11 @@ void _noop(void)
|
|||
static void
|
||||
PyThread__init_thread(void)
|
||||
{
|
||||
/* DO AN INIT BY STARTING THE THREAD */
|
||||
static int dummy = 0;
|
||||
pthread_t thread1;
|
||||
pthread_create(&thread1, NULL, (void *) _noop, &dummy);
|
||||
pthread_join(thread1, NULL);
|
||||
/* DO AN INIT BY STARTING THE THREAD */
|
||||
static int dummy = 0;
|
||||
pthread_t thread1;
|
||||
pthread_create(&thread1, NULL, (void *) _noop, &dummy);
|
||||
pthread_join(thread1, NULL);
|
||||
}
|
||||
|
||||
#else /* !_HAVE_BSDI */
|
||||
|
@ -133,7 +133,7 @@ static void
|
|||
PyThread__init_thread(void)
|
||||
{
|
||||
#if defined(_AIX) && defined(__GNUC__)
|
||||
pthread_init();
|
||||
pthread_init();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -147,59 +147,59 @@ PyThread__init_thread(void)
|
|||
long
|
||||
PyThread_start_new_thread(void (*func)(void *), void *arg)
|
||||
{
|
||||
pthread_t th;
|
||||
int status;
|
||||
pthread_t th;
|
||||
int status;
|
||||
#if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
|
||||
pthread_attr_t attrs;
|
||||
pthread_attr_t attrs;
|
||||
#endif
|
||||
#if defined(THREAD_STACK_SIZE)
|
||||
size_t tss;
|
||||
size_t tss;
|
||||
#endif
|
||||
|
||||
dprintf(("PyThread_start_new_thread called\n"));
|
||||
if (!initialized)
|
||||
PyThread_init_thread();
|
||||
dprintf(("PyThread_start_new_thread called\n"));
|
||||
if (!initialized)
|
||||
PyThread_init_thread();
|
||||
|
||||
#if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
|
||||
if (pthread_attr_init(&attrs) != 0)
|
||||
return -1;
|
||||
if (pthread_attr_init(&attrs) != 0)
|
||||
return -1;
|
||||
#endif
|
||||
#if defined(THREAD_STACK_SIZE)
|
||||
tss = (_pythread_stacksize != 0) ? _pythread_stacksize
|
||||
: THREAD_STACK_SIZE;
|
||||
if (tss != 0) {
|
||||
if (pthread_attr_setstacksize(&attrs, tss) != 0) {
|
||||
pthread_attr_destroy(&attrs);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
tss = (_pythread_stacksize != 0) ? _pythread_stacksize
|
||||
: THREAD_STACK_SIZE;
|
||||
if (tss != 0) {
|
||||
if (pthread_attr_setstacksize(&attrs, tss) != 0) {
|
||||
pthread_attr_destroy(&attrs);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#if defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
|
||||
pthread_attr_setscope(&attrs, PTHREAD_SCOPE_SYSTEM);
|
||||
pthread_attr_setscope(&attrs, PTHREAD_SCOPE_SYSTEM);
|
||||
#endif
|
||||
|
||||
status = pthread_create(&th,
|
||||
status = pthread_create(&th,
|
||||
#if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
|
||||
&attrs,
|
||||
&attrs,
|
||||
#else
|
||||
(pthread_attr_t*)NULL,
|
||||
(pthread_attr_t*)NULL,
|
||||
#endif
|
||||
(void* (*)(void *))func,
|
||||
(void *)arg
|
||||
);
|
||||
(void* (*)(void *))func,
|
||||
(void *)arg
|
||||
);
|
||||
|
||||
#if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED)
|
||||
pthread_attr_destroy(&attrs);
|
||||
pthread_attr_destroy(&attrs);
|
||||
#endif
|
||||
if (status != 0)
|
||||
return -1;
|
||||
if (status != 0)
|
||||
return -1;
|
||||
|
||||
pthread_detach(th);
|
||||
pthread_detach(th);
|
||||
|
||||
#if SIZEOF_PTHREAD_T <= SIZEOF_LONG
|
||||
return (long) th;
|
||||
return (long) th;
|
||||
#else
|
||||
return (long) *(long *) &th;
|
||||
return (long) *(long *) &th;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -210,28 +210,28 @@ PyThread_start_new_thread(void (*func)(void *), void *arg)
|
|||
- It is not clear that the 'volatile' (for AIX?) and ugly casting in the
|
||||
latter return statement (for Alpha OSF/1) are any longer necessary.
|
||||
*/
|
||||
long
|
||||
long
|
||||
PyThread_get_thread_ident(void)
|
||||
{
|
||||
volatile pthread_t threadid;
|
||||
if (!initialized)
|
||||
PyThread_init_thread();
|
||||
/* Jump through some hoops for Alpha OSF/1 */
|
||||
threadid = pthread_self();
|
||||
volatile pthread_t threadid;
|
||||
if (!initialized)
|
||||
PyThread_init_thread();
|
||||
/* Jump through some hoops for Alpha OSF/1 */
|
||||
threadid = pthread_self();
|
||||
#if SIZEOF_PTHREAD_T <= SIZEOF_LONG
|
||||
return (long) threadid;
|
||||
return (long) threadid;
|
||||
#else
|
||||
return (long) *(long *) &threadid;
|
||||
return (long) *(long *) &threadid;
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
PyThread_exit_thread(void)
|
||||
{
|
||||
dprintf(("PyThread_exit_thread called\n"));
|
||||
if (!initialized) {
|
||||
exit(0);
|
||||
}
|
||||
dprintf(("PyThread_exit_thread called\n"));
|
||||
if (!initialized) {
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef USE_SEMAPHORES
|
||||
|
@ -240,47 +240,47 @@ PyThread_exit_thread(void)
|
|||
* Lock support.
|
||||
*/
|
||||
|
||||
PyThread_type_lock
|
||||
PyThread_type_lock
|
||||
PyThread_allocate_lock(void)
|
||||
{
|
||||
sem_t *lock;
|
||||
int status, error = 0;
|
||||
sem_t *lock;
|
||||
int status, error = 0;
|
||||
|
||||
dprintf(("PyThread_allocate_lock called\n"));
|
||||
if (!initialized)
|
||||
PyThread_init_thread();
|
||||
dprintf(("PyThread_allocate_lock called\n"));
|
||||
if (!initialized)
|
||||
PyThread_init_thread();
|
||||
|
||||
lock = (sem_t *)malloc(sizeof(sem_t));
|
||||
lock = (sem_t *)malloc(sizeof(sem_t));
|
||||
|
||||
if (lock) {
|
||||
status = sem_init(lock,0,1);
|
||||
CHECK_STATUS("sem_init");
|
||||
if (lock) {
|
||||
status = sem_init(lock,0,1);
|
||||
CHECK_STATUS("sem_init");
|
||||
|
||||
if (error) {
|
||||
free((void *)lock);
|
||||
lock = NULL;
|
||||
}
|
||||
}
|
||||
if (error) {
|
||||
free((void *)lock);
|
||||
lock = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
dprintf(("PyThread_allocate_lock() -> %p\n", lock));
|
||||
return (PyThread_type_lock)lock;
|
||||
dprintf(("PyThread_allocate_lock() -> %p\n", lock));
|
||||
return (PyThread_type_lock)lock;
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
PyThread_free_lock(PyThread_type_lock lock)
|
||||
{
|
||||
sem_t *thelock = (sem_t *)lock;
|
||||
int status, error = 0;
|
||||
sem_t *thelock = (sem_t *)lock;
|
||||
int status, error = 0;
|
||||
|
||||
dprintf(("PyThread_free_lock(%p) called\n", lock));
|
||||
dprintf(("PyThread_free_lock(%p) called\n", lock));
|
||||
|
||||
if (!thelock)
|
||||
return;
|
||||
if (!thelock)
|
||||
return;
|
||||
|
||||
status = sem_destroy(thelock);
|
||||
CHECK_STATUS("sem_destroy");
|
||||
status = sem_destroy(thelock);
|
||||
CHECK_STATUS("sem_destroy");
|
||||
|
||||
free((void *)thelock);
|
||||
free((void *)thelock);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -292,47 +292,47 @@ PyThread_free_lock(PyThread_type_lock lock)
|
|||
static int
|
||||
fix_status(int status)
|
||||
{
|
||||
return (status == -1) ? errno : status;
|
||||
return (status == -1) ? errno : status;
|
||||
}
|
||||
|
||||
int
|
||||
int
|
||||
PyThread_acquire_lock(PyThread_type_lock lock, int waitflag)
|
||||
{
|
||||
int success;
|
||||
sem_t *thelock = (sem_t *)lock;
|
||||
int status, error = 0;
|
||||
int success;
|
||||
sem_t *thelock = (sem_t *)lock;
|
||||
int status, error = 0;
|
||||
|
||||
dprintf(("PyThread_acquire_lock(%p, %d) called\n", lock, waitflag));
|
||||
dprintf(("PyThread_acquire_lock(%p, %d) called\n", lock, waitflag));
|
||||
|
||||
do {
|
||||
if (waitflag)
|
||||
status = fix_status(sem_wait(thelock));
|
||||
else
|
||||
status = fix_status(sem_trywait(thelock));
|
||||
} while (status == EINTR); /* Retry if interrupted by a signal */
|
||||
do {
|
||||
if (waitflag)
|
||||
status = fix_status(sem_wait(thelock));
|
||||
else
|
||||
status = fix_status(sem_trywait(thelock));
|
||||
} while (status == EINTR); /* Retry if interrupted by a signal */
|
||||
|
||||
if (waitflag) {
|
||||
CHECK_STATUS("sem_wait");
|
||||
} else if (status != EAGAIN) {
|
||||
CHECK_STATUS("sem_trywait");
|
||||
}
|
||||
|
||||
success = (status == 0) ? 1 : 0;
|
||||
if (waitflag) {
|
||||
CHECK_STATUS("sem_wait");
|
||||
} else if (status != EAGAIN) {
|
||||
CHECK_STATUS("sem_trywait");
|
||||
}
|
||||
|
||||
dprintf(("PyThread_acquire_lock(%p, %d) -> %d\n", lock, waitflag, success));
|
||||
return success;
|
||||
success = (status == 0) ? 1 : 0;
|
||||
|
||||
dprintf(("PyThread_acquire_lock(%p, %d) -> %d\n", lock, waitflag, success));
|
||||
return success;
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
PyThread_release_lock(PyThread_type_lock lock)
|
||||
{
|
||||
sem_t *thelock = (sem_t *)lock;
|
||||
int status, error = 0;
|
||||
sem_t *thelock = (sem_t *)lock;
|
||||
int status, error = 0;
|
||||
|
||||
dprintf(("PyThread_release_lock(%p) called\n", lock));
|
||||
dprintf(("PyThread_release_lock(%p) called\n", lock));
|
||||
|
||||
status = sem_post(thelock);
|
||||
CHECK_STATUS("sem_post");
|
||||
status = sem_post(thelock);
|
||||
CHECK_STATUS("sem_post");
|
||||
}
|
||||
|
||||
#else /* USE_SEMAPHORES */
|
||||
|
@ -340,109 +340,109 @@ PyThread_release_lock(PyThread_type_lock lock)
|
|||
/*
|
||||
* Lock support.
|
||||
*/
|
||||
PyThread_type_lock
|
||||
PyThread_type_lock
|
||||
PyThread_allocate_lock(void)
|
||||
{
|
||||
pthread_lock *lock;
|
||||
int status, error = 0;
|
||||
pthread_lock *lock;
|
||||
int status, error = 0;
|
||||
|
||||
dprintf(("PyThread_allocate_lock called\n"));
|
||||
if (!initialized)
|
||||
PyThread_init_thread();
|
||||
dprintf(("PyThread_allocate_lock called\n"));
|
||||
if (!initialized)
|
||||
PyThread_init_thread();
|
||||
|
||||
lock = (pthread_lock *) malloc(sizeof(pthread_lock));
|
||||
if (lock) {
|
||||
memset((void *)lock, '\0', sizeof(pthread_lock));
|
||||
lock->locked = 0;
|
||||
lock = (pthread_lock *) malloc(sizeof(pthread_lock));
|
||||
if (lock) {
|
||||
memset((void *)lock, '\0', sizeof(pthread_lock));
|
||||
lock->locked = 0;
|
||||
|
||||
status = pthread_mutex_init(&lock->mut,
|
||||
pthread_mutexattr_default);
|
||||
CHECK_STATUS("pthread_mutex_init");
|
||||
status = pthread_mutex_init(&lock->mut,
|
||||
pthread_mutexattr_default);
|
||||
CHECK_STATUS("pthread_mutex_init");
|
||||
|
||||
status = pthread_cond_init(&lock->lock_released,
|
||||
pthread_condattr_default);
|
||||
CHECK_STATUS("pthread_cond_init");
|
||||
status = pthread_cond_init(&lock->lock_released,
|
||||
pthread_condattr_default);
|
||||
CHECK_STATUS("pthread_cond_init");
|
||||
|
||||
if (error) {
|
||||
free((void *)lock);
|
||||
lock = 0;
|
||||
}
|
||||
}
|
||||
if (error) {
|
||||
free((void *)lock);
|
||||
lock = 0;
|
||||
}
|
||||
}
|
||||
|
||||
dprintf(("PyThread_allocate_lock() -> %p\n", lock));
|
||||
return (PyThread_type_lock) lock;
|
||||
dprintf(("PyThread_allocate_lock() -> %p\n", lock));
|
||||
return (PyThread_type_lock) lock;
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
PyThread_free_lock(PyThread_type_lock lock)
|
||||
{
|
||||
pthread_lock *thelock = (pthread_lock *)lock;
|
||||
int status, error = 0;
|
||||
pthread_lock *thelock = (pthread_lock *)lock;
|
||||
int status, error = 0;
|
||||
|
||||
dprintf(("PyThread_free_lock(%p) called\n", lock));
|
||||
dprintf(("PyThread_free_lock(%p) called\n", lock));
|
||||
|
||||
status = pthread_mutex_destroy( &thelock->mut );
|
||||
CHECK_STATUS("pthread_mutex_destroy");
|
||||
status = pthread_mutex_destroy( &thelock->mut );
|
||||
CHECK_STATUS("pthread_mutex_destroy");
|
||||
|
||||
status = pthread_cond_destroy( &thelock->lock_released );
|
||||
CHECK_STATUS("pthread_cond_destroy");
|
||||
status = pthread_cond_destroy( &thelock->lock_released );
|
||||
CHECK_STATUS("pthread_cond_destroy");
|
||||
|
||||
free((void *)thelock);
|
||||
free((void *)thelock);
|
||||
}
|
||||
|
||||
int
|
||||
int
|
||||
PyThread_acquire_lock(PyThread_type_lock lock, int waitflag)
|
||||
{
|
||||
int success;
|
||||
pthread_lock *thelock = (pthread_lock *)lock;
|
||||
int status, error = 0;
|
||||
int success;
|
||||
pthread_lock *thelock = (pthread_lock *)lock;
|
||||
int status, error = 0;
|
||||
|
||||
dprintf(("PyThread_acquire_lock(%p, %d) called\n", lock, waitflag));
|
||||
dprintf(("PyThread_acquire_lock(%p, %d) called\n", lock, waitflag));
|
||||
|
||||
status = pthread_mutex_lock( &thelock->mut );
|
||||
CHECK_STATUS("pthread_mutex_lock[1]");
|
||||
success = thelock->locked == 0;
|
||||
status = pthread_mutex_lock( &thelock->mut );
|
||||
CHECK_STATUS("pthread_mutex_lock[1]");
|
||||
success = thelock->locked == 0;
|
||||
|
||||
if ( !success && waitflag ) {
|
||||
/* continue trying until we get the lock */
|
||||
if ( !success && waitflag ) {
|
||||
/* continue trying until we get the lock */
|
||||
|
||||
/* mut must be locked by me -- part of the condition
|
||||
* protocol */
|
||||
while ( thelock->locked ) {
|
||||
status = pthread_cond_wait(&thelock->lock_released,
|
||||
&thelock->mut);
|
||||
CHECK_STATUS("pthread_cond_wait");
|
||||
}
|
||||
success = 1;
|
||||
}
|
||||
if (success) thelock->locked = 1;
|
||||
status = pthread_mutex_unlock( &thelock->mut );
|
||||
CHECK_STATUS("pthread_mutex_unlock[1]");
|
||||
/* mut must be locked by me -- part of the condition
|
||||
* protocol */
|
||||
while ( thelock->locked ) {
|
||||
status = pthread_cond_wait(&thelock->lock_released,
|
||||
&thelock->mut);
|
||||
CHECK_STATUS("pthread_cond_wait");
|
||||
}
|
||||
success = 1;
|
||||
}
|
||||
if (success) thelock->locked = 1;
|
||||
status = pthread_mutex_unlock( &thelock->mut );
|
||||
CHECK_STATUS("pthread_mutex_unlock[1]");
|
||||
|
||||
if (error) success = 0;
|
||||
dprintf(("PyThread_acquire_lock(%p, %d) -> %d\n", lock, waitflag, success));
|
||||
return success;
|
||||
if (error) success = 0;
|
||||
dprintf(("PyThread_acquire_lock(%p, %d) -> %d\n", lock, waitflag, success));
|
||||
return success;
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
PyThread_release_lock(PyThread_type_lock lock)
|
||||
{
|
||||
pthread_lock *thelock = (pthread_lock *)lock;
|
||||
int status, error = 0;
|
||||
pthread_lock *thelock = (pthread_lock *)lock;
|
||||
int status, error = 0;
|
||||
|
||||
dprintf(("PyThread_release_lock(%p) called\n", lock));
|
||||
dprintf(("PyThread_release_lock(%p) called\n", lock));
|
||||
|
||||
status = pthread_mutex_lock( &thelock->mut );
|
||||
CHECK_STATUS("pthread_mutex_lock[3]");
|
||||
status = pthread_mutex_lock( &thelock->mut );
|
||||
CHECK_STATUS("pthread_mutex_lock[3]");
|
||||
|
||||
thelock->locked = 0;
|
||||
thelock->locked = 0;
|
||||
|
||||
status = pthread_mutex_unlock( &thelock->mut );
|
||||
CHECK_STATUS("pthread_mutex_unlock[3]");
|
||||
status = pthread_mutex_unlock( &thelock->mut );
|
||||
CHECK_STATUS("pthread_mutex_unlock[3]");
|
||||
|
||||
/* wake up someone (anyone, if any) waiting on the lock */
|
||||
status = pthread_cond_signal( &thelock->lock_released );
|
||||
CHECK_STATUS("pthread_cond_signal");
|
||||
/* wake up someone (anyone, if any) waiting on the lock */
|
||||
status = pthread_cond_signal( &thelock->lock_released );
|
||||
CHECK_STATUS("pthread_cond_signal");
|
||||
}
|
||||
|
||||
#endif /* USE_SEMAPHORES */
|
||||
|
@ -455,39 +455,39 @@ static int
|
|||
_pythread_pthread_set_stacksize(size_t size)
|
||||
{
|
||||
#if defined(THREAD_STACK_SIZE)
|
||||
pthread_attr_t attrs;
|
||||
size_t tss_min;
|
||||
int rc = 0;
|
||||
pthread_attr_t attrs;
|
||||
size_t tss_min;
|
||||
int rc = 0;
|
||||
#endif
|
||||
|
||||
/* set to default */
|
||||
if (size == 0) {
|
||||
_pythread_stacksize = 0;
|
||||
return 0;
|
||||
}
|
||||
/* set to default */
|
||||
if (size == 0) {
|
||||
_pythread_stacksize = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined(THREAD_STACK_SIZE)
|
||||
#if defined(PTHREAD_STACK_MIN)
|
||||
tss_min = PTHREAD_STACK_MIN > THREAD_STACK_MIN ? PTHREAD_STACK_MIN
|
||||
: THREAD_STACK_MIN;
|
||||
tss_min = PTHREAD_STACK_MIN > THREAD_STACK_MIN ? PTHREAD_STACK_MIN
|
||||
: THREAD_STACK_MIN;
|
||||
#else
|
||||
tss_min = THREAD_STACK_MIN;
|
||||
tss_min = THREAD_STACK_MIN;
|
||||
#endif
|
||||
if (size >= tss_min) {
|
||||
/* validate stack size by setting thread attribute */
|
||||
if (pthread_attr_init(&attrs) == 0) {
|
||||
rc = pthread_attr_setstacksize(&attrs, size);
|
||||
pthread_attr_destroy(&attrs);
|
||||
if (rc == 0) {
|
||||
_pythread_stacksize = size;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
if (size >= tss_min) {
|
||||
/* validate stack size by setting thread attribute */
|
||||
if (pthread_attr_init(&attrs) == 0) {
|
||||
rc = pthread_attr_setstacksize(&attrs, size);
|
||||
pthread_attr_destroy(&attrs);
|
||||
if (rc == 0) {
|
||||
_pythread_stacksize = size;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
#else
|
||||
return -2;
|
||||
return -2;
|
||||
#endif
|
||||
}
|
||||
|
||||
#define THREAD_SET_STACKSIZE(x) _pythread_pthread_set_stacksize(x)
|
||||
#define THREAD_SET_STACKSIZE(x) _pythread_pthread_set_stacksize(x)
|
||||
|
|
|
@ -8,67 +8,67 @@
|
|||
#include <ulocks.h>
|
||||
#include <errno.h>
|
||||
|
||||
#define HDR_SIZE 2680 /* sizeof(ushdr_t) */
|
||||
#define MAXPROC 100 /* max # of threads that can be started */
|
||||
#define HDR_SIZE 2680 /* sizeof(ushdr_t) */
|
||||
#define MAXPROC 100 /* max # of threads that can be started */
|
||||
|
||||
static usptr_t *shared_arena;
|
||||
static ulock_t count_lock; /* protection for some variables */
|
||||
static ulock_t wait_lock; /* lock used to wait for other threads */
|
||||
static int waiting_for_threads; /* protected by count_lock */
|
||||
static int nthreads; /* protected by count_lock */
|
||||
static ulock_t count_lock; /* protection for some variables */
|
||||
static ulock_t wait_lock; /* lock used to wait for other threads */
|
||||
static int waiting_for_threads; /* protected by count_lock */
|
||||
static int nthreads; /* protected by count_lock */
|
||||
static int exit_status;
|
||||
static int exiting; /* we're already exiting (for maybe_exit) */
|
||||
static pid_t my_pid; /* PID of main thread */
|
||||
static int exiting; /* we're already exiting (for maybe_exit) */
|
||||
static pid_t my_pid; /* PID of main thread */
|
||||
static struct pidlist {
|
||||
pid_t parent;
|
||||
pid_t child;
|
||||
} pidlist[MAXPROC]; /* PIDs of other threads; protected by count_lock */
|
||||
static int maxpidindex; /* # of PIDs in pidlist */
|
||||
pid_t parent;
|
||||
pid_t child;
|
||||
} pidlist[MAXPROC]; /* PIDs of other threads; protected by count_lock */
|
||||
static int maxpidindex; /* # of PIDs in pidlist */
|
||||
/*
|
||||
* Initialization.
|
||||
*/
|
||||
static void PyThread__init_thread(void)
|
||||
{
|
||||
#ifdef USE_DL
|
||||
long addr, size;
|
||||
long addr, size;
|
||||
#endif /* USE_DL */
|
||||
|
||||
|
||||
#ifdef USE_DL
|
||||
if ((size = usconfig(CONF_INITSIZE, 64*1024)) < 0)
|
||||
perror("usconfig - CONF_INITSIZE (check)");
|
||||
if (usconfig(CONF_INITSIZE, size) < 0)
|
||||
perror("usconfig - CONF_INITSIZE (reset)");
|
||||
addr = (long) dl_getrange(size + HDR_SIZE);
|
||||
dprintf(("trying to use addr %p-%p for shared arena\n", addr, addr+size));
|
||||
errno = 0;
|
||||
if ((addr = usconfig(CONF_ATTACHADDR, addr)) < 0 && errno != 0)
|
||||
perror("usconfig - CONF_ATTACHADDR (set)");
|
||||
if ((size = usconfig(CONF_INITSIZE, 64*1024)) < 0)
|
||||
perror("usconfig - CONF_INITSIZE (check)");
|
||||
if (usconfig(CONF_INITSIZE, size) < 0)
|
||||
perror("usconfig - CONF_INITSIZE (reset)");
|
||||
addr = (long) dl_getrange(size + HDR_SIZE);
|
||||
dprintf(("trying to use addr %p-%p for shared arena\n", addr, addr+size));
|
||||
errno = 0;
|
||||
if ((addr = usconfig(CONF_ATTACHADDR, addr)) < 0 && errno != 0)
|
||||
perror("usconfig - CONF_ATTACHADDR (set)");
|
||||
#endif /* USE_DL */
|
||||
if (usconfig(CONF_INITUSERS, 16) < 0)
|
||||
perror("usconfig - CONF_INITUSERS");
|
||||
my_pid = getpid(); /* so that we know which is the main thread */
|
||||
if (usconfig(CONF_ARENATYPE, US_SHAREDONLY) < 0)
|
||||
perror("usconfig - CONF_ARENATYPE");
|
||||
usconfig(CONF_LOCKTYPE, US_DEBUG); /* XXX */
|
||||
if (usconfig(CONF_INITUSERS, 16) < 0)
|
||||
perror("usconfig - CONF_INITUSERS");
|
||||
my_pid = getpid(); /* so that we know which is the main thread */
|
||||
if (usconfig(CONF_ARENATYPE, US_SHAREDONLY) < 0)
|
||||
perror("usconfig - CONF_ARENATYPE");
|
||||
usconfig(CONF_LOCKTYPE, US_DEBUG); /* XXX */
|
||||
#ifdef Py_DEBUG
|
||||
if (thread_debug & 4)
|
||||
usconfig(CONF_LOCKTYPE, US_DEBUGPLUS);
|
||||
else if (thread_debug & 2)
|
||||
usconfig(CONF_LOCKTYPE, US_DEBUG);
|
||||
if (thread_debug & 4)
|
||||
usconfig(CONF_LOCKTYPE, US_DEBUGPLUS);
|
||||
else if (thread_debug & 2)
|
||||
usconfig(CONF_LOCKTYPE, US_DEBUG);
|
||||
#endif /* Py_DEBUG */
|
||||
if ((shared_arena = usinit(tmpnam(0))) == 0)
|
||||
perror("usinit");
|
||||
if ((shared_arena = usinit(tmpnam(0))) == 0)
|
||||
perror("usinit");
|
||||
#ifdef USE_DL
|
||||
if (usconfig(CONF_ATTACHADDR, addr) < 0) /* reset address */
|
||||
perror("usconfig - CONF_ATTACHADDR (reset)");
|
||||
if (usconfig(CONF_ATTACHADDR, addr) < 0) /* reset address */
|
||||
perror("usconfig - CONF_ATTACHADDR (reset)");
|
||||
#endif /* USE_DL */
|
||||
if ((count_lock = usnewlock(shared_arena)) == NULL)
|
||||
perror("usnewlock (count_lock)");
|
||||
(void) usinitlock(count_lock);
|
||||
if ((wait_lock = usnewlock(shared_arena)) == NULL)
|
||||
perror("usnewlock (wait_lock)");
|
||||
dprintf(("arena start: %p, arena size: %ld\n", shared_arena, (long) usconfig(CONF_GETSIZE, shared_arena)));
|
||||
if ((count_lock = usnewlock(shared_arena)) == NULL)
|
||||
perror("usnewlock (count_lock)");
|
||||
(void) usinitlock(count_lock);
|
||||
if ((wait_lock = usnewlock(shared_arena)) == NULL)
|
||||
perror("usnewlock (wait_lock)");
|
||||
dprintf(("arena start: %p, arena size: %ld\n", shared_arena, (long) usconfig(CONF_GETSIZE, shared_arena)));
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -77,138 +77,138 @@ static void PyThread__init_thread(void)
|
|||
|
||||
static void clean_threads(void)
|
||||
{
|
||||
int i, j;
|
||||
pid_t mypid, pid;
|
||||
int i, j;
|
||||
pid_t mypid, pid;
|
||||
|
||||
/* clean up any exited threads */
|
||||
mypid = getpid();
|
||||
i = 0;
|
||||
while (i < maxpidindex) {
|
||||
if (pidlist[i].parent == mypid && (pid = pidlist[i].child) > 0) {
|
||||
pid = waitpid(pid, 0, WNOHANG);
|
||||
if (pid > 0) {
|
||||
/* a thread has exited */
|
||||
pidlist[i] = pidlist[--maxpidindex];
|
||||
/* remove references to children of dead proc */
|
||||
for (j = 0; j < maxpidindex; j++)
|
||||
if (pidlist[j].parent == pid)
|
||||
pidlist[j].child = -1;
|
||||
continue; /* don't increment i */
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
/* clean up the list */
|
||||
i = 0;
|
||||
while (i < maxpidindex) {
|
||||
if (pidlist[i].child == -1) {
|
||||
pidlist[i] = pidlist[--maxpidindex];
|
||||
continue; /* don't increment i */
|
||||
}
|
||||
i++;
|
||||
}
|
||||
/* clean up any exited threads */
|
||||
mypid = getpid();
|
||||
i = 0;
|
||||
while (i < maxpidindex) {
|
||||
if (pidlist[i].parent == mypid && (pid = pidlist[i].child) > 0) {
|
||||
pid = waitpid(pid, 0, WNOHANG);
|
||||
if (pid > 0) {
|
||||
/* a thread has exited */
|
||||
pidlist[i] = pidlist[--maxpidindex];
|
||||
/* remove references to children of dead proc */
|
||||
for (j = 0; j < maxpidindex; j++)
|
||||
if (pidlist[j].parent == pid)
|
||||
pidlist[j].child = -1;
|
||||
continue; /* don't increment i */
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
/* clean up the list */
|
||||
i = 0;
|
||||
while (i < maxpidindex) {
|
||||
if (pidlist[i].child == -1) {
|
||||
pidlist[i] = pidlist[--maxpidindex];
|
||||
continue; /* don't increment i */
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
long PyThread_start_new_thread(void (*func)(void *), void *arg)
|
||||
{
|
||||
#ifdef USE_DL
|
||||
long addr, size;
|
||||
static int local_initialized = 0;
|
||||
long addr, size;
|
||||
static int local_initialized = 0;
|
||||
#endif /* USE_DL */
|
||||
int success = 0; /* init not needed when SOLARIS_THREADS and */
|
||||
/* C_THREADS implemented properly */
|
||||
int success = 0; /* init not needed when SOLARIS_THREADS and */
|
||||
/* C_THREADS implemented properly */
|
||||
|
||||
dprintf(("PyThread_start_new_thread called\n"));
|
||||
if (!initialized)
|
||||
PyThread_init_thread();
|
||||
switch (ussetlock(count_lock)) {
|
||||
case 0: return 0;
|
||||
case -1: perror("ussetlock (count_lock)");
|
||||
}
|
||||
if (maxpidindex >= MAXPROC)
|
||||
success = -1;
|
||||
else {
|
||||
dprintf(("PyThread_start_new_thread called\n"));
|
||||
if (!initialized)
|
||||
PyThread_init_thread();
|
||||
switch (ussetlock(count_lock)) {
|
||||
case 0: return 0;
|
||||
case -1: perror("ussetlock (count_lock)");
|
||||
}
|
||||
if (maxpidindex >= MAXPROC)
|
||||
success = -1;
|
||||
else {
|
||||
#ifdef USE_DL
|
||||
if (!local_initialized) {
|
||||
if ((size = usconfig(CONF_INITSIZE, 64*1024)) < 0)
|
||||
perror("usconfig - CONF_INITSIZE (check)");
|
||||
if (usconfig(CONF_INITSIZE, size) < 0)
|
||||
perror("usconfig - CONF_INITSIZE (reset)");
|
||||
addr = (long) dl_getrange(size + HDR_SIZE);
|
||||
dprintf(("trying to use addr %p-%p for sproc\n",
|
||||
addr, addr+size));
|
||||
errno = 0;
|
||||
if ((addr = usconfig(CONF_ATTACHADDR, addr)) < 0 &&
|
||||
errno != 0)
|
||||
perror("usconfig - CONF_ATTACHADDR (set)");
|
||||
}
|
||||
if (!local_initialized) {
|
||||
if ((size = usconfig(CONF_INITSIZE, 64*1024)) < 0)
|
||||
perror("usconfig - CONF_INITSIZE (check)");
|
||||
if (usconfig(CONF_INITSIZE, size) < 0)
|
||||
perror("usconfig - CONF_INITSIZE (reset)");
|
||||
addr = (long) dl_getrange(size + HDR_SIZE);
|
||||
dprintf(("trying to use addr %p-%p for sproc\n",
|
||||
addr, addr+size));
|
||||
errno = 0;
|
||||
if ((addr = usconfig(CONF_ATTACHADDR, addr)) < 0 &&
|
||||
errno != 0)
|
||||
perror("usconfig - CONF_ATTACHADDR (set)");
|
||||
}
|
||||
#endif /* USE_DL */
|
||||
clean_threads();
|
||||
if ((success = sproc(func, PR_SALL, arg)) < 0)
|
||||
perror("sproc");
|
||||
clean_threads();
|
||||
if ((success = sproc(func, PR_SALL, arg)) < 0)
|
||||
perror("sproc");
|
||||
#ifdef USE_DL
|
||||
if (!local_initialized) {
|
||||
if (usconfig(CONF_ATTACHADDR, addr) < 0)
|
||||
/* reset address */
|
||||
perror("usconfig - CONF_ATTACHADDR (reset)");
|
||||
local_initialized = 1;
|
||||
}
|
||||
if (!local_initialized) {
|
||||
if (usconfig(CONF_ATTACHADDR, addr) < 0)
|
||||
/* reset address */
|
||||
perror("usconfig - CONF_ATTACHADDR (reset)");
|
||||
local_initialized = 1;
|
||||
}
|
||||
#endif /* USE_DL */
|
||||
if (success >= 0) {
|
||||
nthreads++;
|
||||
pidlist[maxpidindex].parent = getpid();
|
||||
pidlist[maxpidindex++].child = success;
|
||||
dprintf(("pidlist[%d] = %d\n",
|
||||
maxpidindex-1, success));
|
||||
}
|
||||
}
|
||||
if (usunsetlock(count_lock) < 0)
|
||||
perror("usunsetlock (count_lock)");
|
||||
return success;
|
||||
if (success >= 0) {
|
||||
nthreads++;
|
||||
pidlist[maxpidindex].parent = getpid();
|
||||
pidlist[maxpidindex++].child = success;
|
||||
dprintf(("pidlist[%d] = %d\n",
|
||||
maxpidindex-1, success));
|
||||
}
|
||||
}
|
||||
if (usunsetlock(count_lock) < 0)
|
||||
perror("usunsetlock (count_lock)");
|
||||
return success;
|
||||
}
|
||||
|
||||
long PyThread_get_thread_ident(void)
|
||||
{
|
||||
return getpid();
|
||||
return getpid();
|
||||
}
|
||||
|
||||
void PyThread_exit_thread(void)
|
||||
{
|
||||
dprintf(("PyThread_exit_thread called\n"));
|
||||
if (!initialized)
|
||||
exit(0);
|
||||
if (ussetlock(count_lock) < 0)
|
||||
perror("ussetlock (count_lock)");
|
||||
nthreads--;
|
||||
if (getpid() == my_pid) {
|
||||
/* main thread; wait for other threads to exit */
|
||||
exiting = 1;
|
||||
waiting_for_threads = 1;
|
||||
if (ussetlock(wait_lock) < 0)
|
||||
perror("ussetlock (wait_lock)");
|
||||
for (;;) {
|
||||
if (nthreads < 0) {
|
||||
dprintf(("really exit (%d)\n", exit_status));
|
||||
exit(exit_status);
|
||||
}
|
||||
if (usunsetlock(count_lock) < 0)
|
||||
perror("usunsetlock (count_lock)");
|
||||
dprintf(("waiting for other threads (%d)\n", nthreads));
|
||||
if (ussetlock(wait_lock) < 0)
|
||||
perror("ussetlock (wait_lock)");
|
||||
if (ussetlock(count_lock) < 0)
|
||||
perror("ussetlock (count_lock)");
|
||||
}
|
||||
}
|
||||
/* not the main thread */
|
||||
if (waiting_for_threads) {
|
||||
dprintf(("main thread is waiting\n"));
|
||||
if (usunsetlock(wait_lock) < 0)
|
||||
perror("usunsetlock (wait_lock)");
|
||||
}
|
||||
if (usunsetlock(count_lock) < 0)
|
||||
perror("usunsetlock (count_lock)");
|
||||
_exit(0);
|
||||
dprintf(("PyThread_exit_thread called\n"));
|
||||
if (!initialized)
|
||||
exit(0);
|
||||
if (ussetlock(count_lock) < 0)
|
||||
perror("ussetlock (count_lock)");
|
||||
nthreads--;
|
||||
if (getpid() == my_pid) {
|
||||
/* main thread; wait for other threads to exit */
|
||||
exiting = 1;
|
||||
waiting_for_threads = 1;
|
||||
if (ussetlock(wait_lock) < 0)
|
||||
perror("ussetlock (wait_lock)");
|
||||
for (;;) {
|
||||
if (nthreads < 0) {
|
||||
dprintf(("really exit (%d)\n", exit_status));
|
||||
exit(exit_status);
|
||||
}
|
||||
if (usunsetlock(count_lock) < 0)
|
||||
perror("usunsetlock (count_lock)");
|
||||
dprintf(("waiting for other threads (%d)\n", nthreads));
|
||||
if (ussetlock(wait_lock) < 0)
|
||||
perror("ussetlock (wait_lock)");
|
||||
if (ussetlock(count_lock) < 0)
|
||||
perror("ussetlock (count_lock)");
|
||||
}
|
||||
}
|
||||
/* not the main thread */
|
||||
if (waiting_for_threads) {
|
||||
dprintf(("main thread is waiting\n"));
|
||||
if (usunsetlock(wait_lock) < 0)
|
||||
perror("usunsetlock (wait_lock)");
|
||||
}
|
||||
if (usunsetlock(count_lock) < 0)
|
||||
perror("usunsetlock (count_lock)");
|
||||
_exit(0);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -216,44 +216,44 @@ void PyThread_exit_thread(void)
|
|||
*/
|
||||
PyThread_type_lock PyThread_allocate_lock(void)
|
||||
{
|
||||
ulock_t lock;
|
||||
ulock_t lock;
|
||||
|
||||
dprintf(("PyThread_allocate_lock called\n"));
|
||||
if (!initialized)
|
||||
PyThread_init_thread();
|
||||
dprintf(("PyThread_allocate_lock called\n"));
|
||||
if (!initialized)
|
||||
PyThread_init_thread();
|
||||
|
||||
if ((lock = usnewlock(shared_arena)) == NULL)
|
||||
perror("usnewlock");
|
||||
(void) usinitlock(lock);
|
||||
dprintf(("PyThread_allocate_lock() -> %p\n", lock));
|
||||
return (PyThread_type_lock) lock;
|
||||
if ((lock = usnewlock(shared_arena)) == NULL)
|
||||
perror("usnewlock");
|
||||
(void) usinitlock(lock);
|
||||
dprintf(("PyThread_allocate_lock() -> %p\n", lock));
|
||||
return (PyThread_type_lock) lock;
|
||||
}
|
||||
|
||||
void PyThread_free_lock(PyThread_type_lock lock)
|
||||
{
|
||||
dprintf(("PyThread_free_lock(%p) called\n", lock));
|
||||
usfreelock((ulock_t) lock, shared_arena);
|
||||
dprintf(("PyThread_free_lock(%p) called\n", lock));
|
||||
usfreelock((ulock_t) lock, shared_arena);
|
||||
}
|
||||
|
||||
int PyThread_acquire_lock(PyThread_type_lock lock, int waitflag)
|
||||
{
|
||||
int success;
|
||||
int success;
|
||||
|
||||
dprintf(("PyThread_acquire_lock(%p, %d) called\n", lock, waitflag));
|
||||
errno = 0; /* clear it just in case */
|
||||
if (waitflag)
|
||||
success = ussetlock((ulock_t) lock);
|
||||
else
|
||||
success = uscsetlock((ulock_t) lock, 1); /* Try it once */
|
||||
if (success < 0)
|
||||
perror(waitflag ? "ussetlock" : "uscsetlock");
|
||||
dprintf(("PyThread_acquire_lock(%p, %d) -> %d\n", lock, waitflag, success));
|
||||
return success;
|
||||
dprintf(("PyThread_acquire_lock(%p, %d) called\n", lock, waitflag));
|
||||
errno = 0; /* clear it just in case */
|
||||
if (waitflag)
|
||||
success = ussetlock((ulock_t) lock);
|
||||
else
|
||||
success = uscsetlock((ulock_t) lock, 1); /* Try it once */
|
||||
if (success < 0)
|
||||
perror(waitflag ? "ussetlock" : "uscsetlock");
|
||||
dprintf(("PyThread_acquire_lock(%p, %d) -> %d\n", lock, waitflag, success));
|
||||
return success;
|
||||
}
|
||||
|
||||
void PyThread_release_lock(PyThread_type_lock lock)
|
||||
{
|
||||
dprintf(("PyThread_release_lock(%p) called\n", lock));
|
||||
if (usunsetlock((ulock_t) lock) < 0)
|
||||
perror("usunsetlock");
|
||||
dprintf(("PyThread_release_lock(%p) called\n", lock));
|
||||
if (usunsetlock((ulock_t) lock) < 0)
|
||||
perror("usunsetlock");
|
||||
}
|
||||
|
|
|
@ -17,114 +17,114 @@ static void PyThread__init_thread(void)
|
|||
* Thread support.
|
||||
*/
|
||||
struct func_arg {
|
||||
void (*func)(void *);
|
||||
void *arg;
|
||||
void (*func)(void *);
|
||||
void *arg;
|
||||
};
|
||||
|
||||
static void *
|
||||
new_func(void *funcarg)
|
||||
{
|
||||
void (*func)(void *);
|
||||
void *arg;
|
||||
void (*func)(void *);
|
||||
void *arg;
|
||||
|
||||
func = ((struct func_arg *) funcarg)->func;
|
||||
arg = ((struct func_arg *) funcarg)->arg;
|
||||
free(funcarg);
|
||||
(*func)(arg);
|
||||
return 0;
|
||||
func = ((struct func_arg *) funcarg)->func;
|
||||
arg = ((struct func_arg *) funcarg)->arg;
|
||||
free(funcarg);
|
||||
(*func)(arg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
long
|
||||
PyThread_start_new_thread(void (*func)(void *), void *arg)
|
||||
{
|
||||
thread_t tid;
|
||||
struct func_arg *funcarg;
|
||||
thread_t tid;
|
||||
struct func_arg *funcarg;
|
||||
|
||||
dprintf(("PyThread_start_new_thread called\n"));
|
||||
if (!initialized)
|
||||
PyThread_init_thread();
|
||||
funcarg = (struct func_arg *) malloc(sizeof(struct func_arg));
|
||||
funcarg->func = func;
|
||||
funcarg->arg = arg;
|
||||
if (thr_create(0, 0, new_func, funcarg,
|
||||
THR_DETACHED | THR_NEW_LWP, &tid)) {
|
||||
perror("thr_create");
|
||||
free((void *) funcarg);
|
||||
return -1;
|
||||
}
|
||||
return tid;
|
||||
dprintf(("PyThread_start_new_thread called\n"));
|
||||
if (!initialized)
|
||||
PyThread_init_thread();
|
||||
funcarg = (struct func_arg *) malloc(sizeof(struct func_arg));
|
||||
funcarg->func = func;
|
||||
funcarg->arg = arg;
|
||||
if (thr_create(0, 0, new_func, funcarg,
|
||||
THR_DETACHED | THR_NEW_LWP, &tid)) {
|
||||
perror("thr_create");
|
||||
free((void *) funcarg);
|
||||
return -1;
|
||||
}
|
||||
return tid;
|
||||
}
|
||||
|
||||
long
|
||||
PyThread_get_thread_ident(void)
|
||||
{
|
||||
if (!initialized)
|
||||
PyThread_init_thread();
|
||||
return thr_self();
|
||||
if (!initialized)
|
||||
PyThread_init_thread();
|
||||
return thr_self();
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
PyThread_exit_thread(void)
|
||||
{
|
||||
dprintf(("PyThread_exit_thread called\n"));
|
||||
if (!initialized)
|
||||
exit(0);
|
||||
thr_exit(0);
|
||||
dprintf(("PyThread_exit_thread called\n"));
|
||||
if (!initialized)
|
||||
exit(0);
|
||||
thr_exit(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Lock support.
|
||||
*/
|
||||
PyThread_type_lock
|
||||
PyThread_type_lock
|
||||
PyThread_allocate_lock(void)
|
||||
{
|
||||
mutex_t *lock;
|
||||
mutex_t *lock;
|
||||
|
||||
dprintf(("PyThread_allocate_lock called\n"));
|
||||
if (!initialized)
|
||||
PyThread_init_thread();
|
||||
dprintf(("PyThread_allocate_lock called\n"));
|
||||
if (!initialized)
|
||||
PyThread_init_thread();
|
||||
|
||||
lock = (mutex_t *) malloc(sizeof(mutex_t));
|
||||
if (mutex_init(lock, USYNC_THREAD, 0)) {
|
||||
perror("mutex_init");
|
||||
free((void *) lock);
|
||||
lock = 0;
|
||||
}
|
||||
dprintf(("PyThread_allocate_lock() -> %p\n", lock));
|
||||
return (PyThread_type_lock) lock;
|
||||
lock = (mutex_t *) malloc(sizeof(mutex_t));
|
||||
if (mutex_init(lock, USYNC_THREAD, 0)) {
|
||||
perror("mutex_init");
|
||||
free((void *) lock);
|
||||
lock = 0;
|
||||
}
|
||||
dprintf(("PyThread_allocate_lock() -> %p\n", lock));
|
||||
return (PyThread_type_lock) lock;
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
PyThread_free_lock(PyThread_type_lock lock)
|
||||
{
|
||||
dprintf(("PyThread_free_lock(%p) called\n", lock));
|
||||
mutex_destroy((mutex_t *) lock);
|
||||
free((void *) lock);
|
||||
dprintf(("PyThread_free_lock(%p) called\n", lock));
|
||||
mutex_destroy((mutex_t *) lock);
|
||||
free((void *) lock);
|
||||
}
|
||||
|
||||
int
|
||||
int
|
||||
PyThread_acquire_lock(PyThread_type_lock lock, int waitflag)
|
||||
{
|
||||
int success;
|
||||
int success;
|
||||
|
||||
dprintf(("PyThread_acquire_lock(%p, %d) called\n", lock, waitflag));
|
||||
if (waitflag)
|
||||
success = mutex_lock((mutex_t *) lock);
|
||||
else
|
||||
success = mutex_trylock((mutex_t *) lock);
|
||||
if (success < 0)
|
||||
perror(waitflag ? "mutex_lock" : "mutex_trylock");
|
||||
else
|
||||
success = !success; /* solaris does it the other way round */
|
||||
dprintf(("PyThread_acquire_lock(%p, %d) -> %d\n", lock, waitflag, success));
|
||||
return success;
|
||||
dprintf(("PyThread_acquire_lock(%p, %d) called\n", lock, waitflag));
|
||||
if (waitflag)
|
||||
success = mutex_lock((mutex_t *) lock);
|
||||
else
|
||||
success = mutex_trylock((mutex_t *) lock);
|
||||
if (success < 0)
|
||||
perror(waitflag ? "mutex_lock" : "mutex_trylock");
|
||||
else
|
||||
success = !success; /* solaris does it the other way round */
|
||||
dprintf(("PyThread_acquire_lock(%p, %d) -> %d\n", lock, waitflag, success));
|
||||
return success;
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
PyThread_release_lock(PyThread_type_lock lock)
|
||||
{
|
||||
dprintf(("PyThread_release_lock(%p) called\n", lock));
|
||||
if (mutex_unlock((mutex_t *) lock))
|
||||
perror("mutex_unlock");
|
||||
dprintf(("PyThread_release_lock(%p) called\n", lock));
|
||||
if (mutex_unlock((mutex_t *) lock))
|
||||
perror("mutex_unlock");
|
||||
}
|
||||
|
|
|
@ -24,21 +24,21 @@ static void PyThread__init_thread(void)
|
|||
*/
|
||||
long PyThread_start_new_thread(void (*func)(void *), void *arg)
|
||||
{
|
||||
long rv;
|
||||
int success = -1;
|
||||
long rv;
|
||||
int success = -1;
|
||||
|
||||
dprintf(("%ld: PyThread_start_new_thread called\n", PyThread_get_thread_ident()));
|
||||
if (!initialized)
|
||||
PyThread_init_thread();
|
||||
dprintf(("%ld: PyThread_start_new_thread called\n", PyThread_get_thread_ident()));
|
||||
if (!initialized)
|
||||
PyThread_init_thread();
|
||||
|
||||
rv = _beginthread(func, 0, arg); /* use default stack size */
|
||||
|
||||
if (rv != -1) {
|
||||
success = 0;
|
||||
dprintf(("%ld: PyThread_start_new_thread succeeded:\n", PyThread_get_thread_ident()));
|
||||
}
|
||||
rv = _beginthread(func, 0, arg); /* use default stack size */
|
||||
|
||||
return success;
|
||||
if (rv != -1) {
|
||||
success = 0;
|
||||
dprintf(("%ld: PyThread_start_new_thread succeeded:\n", PyThread_get_thread_ident()));
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -47,18 +47,18 @@ long PyThread_start_new_thread(void (*func)(void *), void *arg)
|
|||
*/
|
||||
long PyThread_get_thread_ident(void)
|
||||
{
|
||||
if (!initialized)
|
||||
PyThread_init_thread();
|
||||
|
||||
return GetCurrentThreadId();
|
||||
if (!initialized)
|
||||
PyThread_init_thread();
|
||||
|
||||
return GetCurrentThreadId();
|
||||
}
|
||||
|
||||
void PyThread_exit_thread(void)
|
||||
{
|
||||
dprintf(("%ld: PyThread_exit_thread called\n", PyThread_get_thread_ident()));
|
||||
if (!initialized)
|
||||
exit(0);
|
||||
_endthread();
|
||||
dprintf(("%ld: PyThread_exit_thread called\n", PyThread_get_thread_ident()));
|
||||
if (!initialized)
|
||||
exit(0);
|
||||
_endthread();
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -72,12 +72,12 @@ PyThread_type_lock PyThread_allocate_lock(void)
|
|||
|
||||
dprintf(("PyThread_allocate_lock called\n"));
|
||||
if (!initialized)
|
||||
PyThread_init_thread();
|
||||
PyThread_init_thread();
|
||||
|
||||
aLock = CreateEvent(NULL, /* Security attributes */
|
||||
0, /* Manual-Reset */
|
||||
1, /* Is initially signalled */
|
||||
NULL); /* Name of event */
|
||||
0, /* Manual-Reset */
|
||||
1, /* Is initially signalled */
|
||||
NULL); /* Name of event */
|
||||
|
||||
dprintf(("%ld: PyThread_allocate_lock() -> %p\n", PyThread_get_thread_ident(), aLock));
|
||||
|
||||
|
@ -107,22 +107,22 @@ int PyThread_acquire_lock(PyThread_type_lock aLock, int waitflag)
|
|||
#ifndef DEBUG
|
||||
waitResult = WaitForSingleObject(aLock, (waitflag ? INFINITE : 0));
|
||||
#else
|
||||
/* To aid in debugging, we regularly wake up. This allows us to
|
||||
break into the debugger */
|
||||
while (TRUE) {
|
||||
waitResult = WaitForSingleObject(aLock, waitflag ? 3000 : 0);
|
||||
if (waitflag==0 || (waitflag && waitResult == WAIT_OBJECT_0))
|
||||
break;
|
||||
}
|
||||
/* To aid in debugging, we regularly wake up. This allows us to
|
||||
break into the debugger */
|
||||
while (TRUE) {
|
||||
waitResult = WaitForSingleObject(aLock, waitflag ? 3000 : 0);
|
||||
if (waitflag==0 || (waitflag && waitResult == WAIT_OBJECT_0))
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (waitResult != WAIT_OBJECT_0) {
|
||||
success = 0; /* We failed */
|
||||
success = 0; /* We failed */
|
||||
}
|
||||
|
||||
dprintf(("%ld: PyThread_acquire_lock(%p, %d) -> %d\n", PyThread_get_thread_ident(),aLock, waitflag, success));
|
||||
dprintf(("%ld: PyThread_acquire_lock(%p, %d) -> %d\n", PyThread_get_thread_ident(),aLock, waitflag, success));
|
||||
|
||||
return success;
|
||||
return success;
|
||||
}
|
||||
|
||||
void PyThread_release_lock(PyThread_type_lock aLock)
|
||||
|
@ -130,7 +130,7 @@ void PyThread_release_lock(PyThread_type_lock aLock)
|
|||
dprintf(("%ld: PyThread_release_lock(%p) called\n", PyThread_get_thread_ident(),aLock));
|
||||
|
||||
if (!SetEvent(aLock))
|
||||
dprintf(("%ld: Could not PyThread_release_lock(%p) error: %l\n", PyThread_get_thread_ident(), aLock, GetLastError()));
|
||||
dprintf(("%ld: Could not PyThread_release_lock(%p) error: %l\n", PyThread_get_thread_ident(), aLock, GetLastError()));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -12,272 +12,272 @@
|
|||
#define OFF(x) offsetof(PyTracebackObject, x)
|
||||
|
||||
static PyMemberDef tb_memberlist[] = {
|
||||
{"tb_next", T_OBJECT, OFF(tb_next), READONLY},
|
||||
{"tb_frame", T_OBJECT, OFF(tb_frame), READONLY},
|
||||
{"tb_lasti", T_INT, OFF(tb_lasti), READONLY},
|
||||
{"tb_lineno", T_INT, OFF(tb_lineno), READONLY},
|
||||
{NULL} /* Sentinel */
|
||||
{"tb_next", T_OBJECT, OFF(tb_next), READONLY},
|
||||
{"tb_frame", T_OBJECT, OFF(tb_frame), READONLY},
|
||||
{"tb_lasti", T_INT, OFF(tb_lasti), READONLY},
|
||||
{"tb_lineno", T_INT, OFF(tb_lineno), READONLY},
|
||||
{NULL} /* Sentinel */
|
||||
};
|
||||
|
||||
static void
|
||||
tb_dealloc(PyTracebackObject *tb)
|
||||
{
|
||||
PyObject_GC_UnTrack(tb);
|
||||
Py_TRASHCAN_SAFE_BEGIN(tb)
|
||||
Py_XDECREF(tb->tb_next);
|
||||
Py_XDECREF(tb->tb_frame);
|
||||
PyObject_GC_Del(tb);
|
||||
Py_TRASHCAN_SAFE_END(tb)
|
||||
PyObject_GC_UnTrack(tb);
|
||||
Py_TRASHCAN_SAFE_BEGIN(tb)
|
||||
Py_XDECREF(tb->tb_next);
|
||||
Py_XDECREF(tb->tb_frame);
|
||||
PyObject_GC_Del(tb);
|
||||
Py_TRASHCAN_SAFE_END(tb)
|
||||
}
|
||||
|
||||
static int
|
||||
tb_traverse(PyTracebackObject *tb, visitproc visit, void *arg)
|
||||
{
|
||||
Py_VISIT(tb->tb_next);
|
||||
Py_VISIT(tb->tb_frame);
|
||||
return 0;
|
||||
Py_VISIT(tb->tb_next);
|
||||
Py_VISIT(tb->tb_frame);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
tb_clear(PyTracebackObject *tb)
|
||||
{
|
||||
Py_CLEAR(tb->tb_next);
|
||||
Py_CLEAR(tb->tb_frame);
|
||||
Py_CLEAR(tb->tb_next);
|
||||
Py_CLEAR(tb->tb_frame);
|
||||
}
|
||||
|
||||
PyTypeObject PyTraceBack_Type = {
|
||||
PyVarObject_HEAD_INIT(&PyType_Type, 0)
|
||||
"traceback",
|
||||
sizeof(PyTracebackObject),
|
||||
0,
|
||||
(destructor)tb_dealloc, /*tp_dealloc*/
|
||||
0, /*tp_print*/
|
||||
0, /*tp_getattr*/
|
||||
0, /*tp_setattr*/
|
||||
0, /*tp_compare*/
|
||||
0, /*tp_repr*/
|
||||
0, /*tp_as_number*/
|
||||
0, /*tp_as_sequence*/
|
||||
0, /*tp_as_mapping*/
|
||||
0, /* tp_hash */
|
||||
0, /* tp_call */
|
||||
0, /* tp_str */
|
||||
0, /* tp_getattro */
|
||||
0, /* tp_setattro */
|
||||
0, /* tp_as_buffer */
|
||||
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
|
||||
0, /* tp_doc */
|
||||
(traverseproc)tb_traverse, /* tp_traverse */
|
||||
(inquiry)tb_clear, /* tp_clear */
|
||||
0, /* tp_richcompare */
|
||||
0, /* tp_weaklistoffset */
|
||||
0, /* tp_iter */
|
||||
0, /* tp_iternext */
|
||||
0, /* tp_methods */
|
||||
tb_memberlist, /* tp_members */
|
||||
0, /* tp_getset */
|
||||
0, /* tp_base */
|
||||
0, /* tp_dict */
|
||||
PyVarObject_HEAD_INIT(&PyType_Type, 0)
|
||||
"traceback",
|
||||
sizeof(PyTracebackObject),
|
||||
0,
|
||||
(destructor)tb_dealloc, /*tp_dealloc*/
|
||||
0, /*tp_print*/
|
||||
0, /*tp_getattr*/
|
||||
0, /*tp_setattr*/
|
||||
0, /*tp_compare*/
|
||||
0, /*tp_repr*/
|
||||
0, /*tp_as_number*/
|
||||
0, /*tp_as_sequence*/
|
||||
0, /*tp_as_mapping*/
|
||||
0, /* tp_hash */
|
||||
0, /* tp_call */
|
||||
0, /* tp_str */
|
||||
0, /* tp_getattro */
|
||||
0, /* tp_setattro */
|
||||
0, /* tp_as_buffer */
|
||||
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
|
||||
0, /* tp_doc */
|
||||
(traverseproc)tb_traverse, /* tp_traverse */
|
||||
(inquiry)tb_clear, /* tp_clear */
|
||||
0, /* tp_richcompare */
|
||||
0, /* tp_weaklistoffset */
|
||||
0, /* tp_iter */
|
||||
0, /* tp_iternext */
|
||||
0, /* tp_methods */
|
||||
tb_memberlist, /* tp_members */
|
||||
0, /* tp_getset */
|
||||
0, /* tp_base */
|
||||
0, /* tp_dict */
|
||||
};
|
||||
|
||||
static PyTracebackObject *
|
||||
newtracebackobject(PyTracebackObject *next, PyFrameObject *frame)
|
||||
{
|
||||
PyTracebackObject *tb;
|
||||
if ((next != NULL && !PyTraceBack_Check(next)) ||
|
||||
frame == NULL || !PyFrame_Check(frame)) {
|
||||
PyErr_BadInternalCall();
|
||||
return NULL;
|
||||
}
|
||||
tb = PyObject_GC_New(PyTracebackObject, &PyTraceBack_Type);
|
||||
if (tb != NULL) {
|
||||
Py_XINCREF(next);
|
||||
tb->tb_next = next;
|
||||
Py_XINCREF(frame);
|
||||
tb->tb_frame = frame;
|
||||
tb->tb_lasti = frame->f_lasti;
|
||||
tb->tb_lineno = PyFrame_GetLineNumber(frame);
|
||||
PyObject_GC_Track(tb);
|
||||
}
|
||||
return tb;
|
||||
PyTracebackObject *tb;
|
||||
if ((next != NULL && !PyTraceBack_Check(next)) ||
|
||||
frame == NULL || !PyFrame_Check(frame)) {
|
||||
PyErr_BadInternalCall();
|
||||
return NULL;
|
||||
}
|
||||
tb = PyObject_GC_New(PyTracebackObject, &PyTraceBack_Type);
|
||||
if (tb != NULL) {
|
||||
Py_XINCREF(next);
|
||||
tb->tb_next = next;
|
||||
Py_XINCREF(frame);
|
||||
tb->tb_frame = frame;
|
||||
tb->tb_lasti = frame->f_lasti;
|
||||
tb->tb_lineno = PyFrame_GetLineNumber(frame);
|
||||
PyObject_GC_Track(tb);
|
||||
}
|
||||
return tb;
|
||||
}
|
||||
|
||||
int
|
||||
PyTraceBack_Here(PyFrameObject *frame)
|
||||
{
|
||||
PyThreadState *tstate = PyThreadState_GET();
|
||||
PyTracebackObject *oldtb = (PyTracebackObject *) tstate->curexc_traceback;
|
||||
PyTracebackObject *tb = newtracebackobject(oldtb, frame);
|
||||
if (tb == NULL)
|
||||
return -1;
|
||||
tstate->curexc_traceback = (PyObject *)tb;
|
||||
Py_XDECREF(oldtb);
|
||||
return 0;
|
||||
PyThreadState *tstate = PyThreadState_GET();
|
||||
PyTracebackObject *oldtb = (PyTracebackObject *) tstate->curexc_traceback;
|
||||
PyTracebackObject *tb = newtracebackobject(oldtb, frame);
|
||||
if (tb == NULL)
|
||||
return -1;
|
||||
tstate->curexc_traceback = (PyObject *)tb;
|
||||
Py_XDECREF(oldtb);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
_Py_DisplaySourceLine(PyObject *f, const char *filename, int lineno, int indent)
|
||||
{
|
||||
int err = 0;
|
||||
FILE *xfp = NULL;
|
||||
char linebuf[2000];
|
||||
int i;
|
||||
char namebuf[MAXPATHLEN+1];
|
||||
int err = 0;
|
||||
FILE *xfp = NULL;
|
||||
char linebuf[2000];
|
||||
int i;
|
||||
char namebuf[MAXPATHLEN+1];
|
||||
|
||||
if (filename == NULL)
|
||||
return -1;
|
||||
/* This is needed by Emacs' compile command */
|
||||
if (filename == NULL)
|
||||
return -1;
|
||||
/* This is needed by Emacs' compile command */
|
||||
#define FMT " File \"%.500s\", line %d, in %.500s\n"
|
||||
xfp = fopen(filename, "r" PY_STDIOTEXTMODE);
|
||||
if (xfp == NULL) {
|
||||
/* Search tail of filename in sys.path before giving up */
|
||||
PyObject *path;
|
||||
const char *tail = strrchr(filename, SEP);
|
||||
if (tail == NULL)
|
||||
tail = filename;
|
||||
else
|
||||
tail++;
|
||||
path = PySys_GetObject("path");
|
||||
if (path != NULL && PyList_Check(path)) {
|
||||
Py_ssize_t _npath = PyList_Size(path);
|
||||
int npath = Py_SAFE_DOWNCAST(_npath, Py_ssize_t, int);
|
||||
size_t taillen = strlen(tail);
|
||||
for (i = 0; i < npath; i++) {
|
||||
PyObject *v = PyList_GetItem(path, i);
|
||||
if (v == NULL) {
|
||||
PyErr_Clear();
|
||||
break;
|
||||
}
|
||||
if (PyString_Check(v)) {
|
||||
size_t len;
|
||||
len = PyString_GET_SIZE(v);
|
||||
if (len + 1 + taillen >= MAXPATHLEN)
|
||||
continue; /* Too long */
|
||||
strcpy(namebuf, PyString_AsString(v));
|
||||
if (strlen(namebuf) != len)
|
||||
continue; /* v contains '\0' */
|
||||
if (len > 0 && namebuf[len-1] != SEP)
|
||||
namebuf[len++] = SEP;
|
||||
strcpy(namebuf+len, tail);
|
||||
xfp = fopen(namebuf, "r" PY_STDIOTEXTMODE);
|
||||
if (xfp != NULL) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
xfp = fopen(filename, "r" PY_STDIOTEXTMODE);
|
||||
if (xfp == NULL) {
|
||||
/* Search tail of filename in sys.path before giving up */
|
||||
PyObject *path;
|
||||
const char *tail = strrchr(filename, SEP);
|
||||
if (tail == NULL)
|
||||
tail = filename;
|
||||
else
|
||||
tail++;
|
||||
path = PySys_GetObject("path");
|
||||
if (path != NULL && PyList_Check(path)) {
|
||||
Py_ssize_t _npath = PyList_Size(path);
|
||||
int npath = Py_SAFE_DOWNCAST(_npath, Py_ssize_t, int);
|
||||
size_t taillen = strlen(tail);
|
||||
for (i = 0; i < npath; i++) {
|
||||
PyObject *v = PyList_GetItem(path, i);
|
||||
if (v == NULL) {
|
||||
PyErr_Clear();
|
||||
break;
|
||||
}
|
||||
if (PyString_Check(v)) {
|
||||
size_t len;
|
||||
len = PyString_GET_SIZE(v);
|
||||
if (len + 1 + taillen >= MAXPATHLEN)
|
||||
continue; /* Too long */
|
||||
strcpy(namebuf, PyString_AsString(v));
|
||||
if (strlen(namebuf) != len)
|
||||
continue; /* v contains '\0' */
|
||||
if (len > 0 && namebuf[len-1] != SEP)
|
||||
namebuf[len++] = SEP;
|
||||
strcpy(namebuf+len, tail);
|
||||
xfp = fopen(namebuf, "r" PY_STDIOTEXTMODE);
|
||||
if (xfp != NULL) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (xfp == NULL)
|
||||
return err;
|
||||
if (err != 0) {
|
||||
fclose(xfp);
|
||||
return err;
|
||||
if (xfp == NULL)
|
||||
return err;
|
||||
if (err != 0) {
|
||||
fclose(xfp);
|
||||
return err;
|
||||
}
|
||||
|
||||
for (i = 0; i < lineno; i++) {
|
||||
char* pLastChar = &linebuf[sizeof(linebuf)-2];
|
||||
do {
|
||||
*pLastChar = '\0';
|
||||
if (Py_UniversalNewlineFgets(linebuf, sizeof linebuf, xfp, NULL) == NULL)
|
||||
break;
|
||||
/* fgets read *something*; if it didn't get as
|
||||
far as pLastChar, it must have found a newline
|
||||
or hit the end of the file; if pLastChar is \n,
|
||||
it obviously found a newline; else we haven't
|
||||
yet seen a newline, so must continue */
|
||||
} while (*pLastChar != '\0' && *pLastChar != '\n');
|
||||
}
|
||||
if (i == lineno) {
|
||||
char buf[11];
|
||||
char *p = linebuf;
|
||||
while (*p == ' ' || *p == '\t' || *p == '\014')
|
||||
p++;
|
||||
|
||||
/* Write some spaces before the line */
|
||||
strcpy(buf, " ");
|
||||
assert (strlen(buf) == 10);
|
||||
while (indent > 0) {
|
||||
if(indent < 10)
|
||||
buf[indent] = '\0';
|
||||
err = PyFile_WriteString(buf, f);
|
||||
if (err != 0)
|
||||
break;
|
||||
indent -= 10;
|
||||
}
|
||||
|
||||
for (i = 0; i < lineno; i++) {
|
||||
char* pLastChar = &linebuf[sizeof(linebuf)-2];
|
||||
do {
|
||||
*pLastChar = '\0';
|
||||
if (Py_UniversalNewlineFgets(linebuf, sizeof linebuf, xfp, NULL) == NULL)
|
||||
break;
|
||||
/* fgets read *something*; if it didn't get as
|
||||
far as pLastChar, it must have found a newline
|
||||
or hit the end of the file; if pLastChar is \n,
|
||||
it obviously found a newline; else we haven't
|
||||
yet seen a newline, so must continue */
|
||||
} while (*pLastChar != '\0' && *pLastChar != '\n');
|
||||
}
|
||||
if (i == lineno) {
|
||||
char buf[11];
|
||||
char *p = linebuf;
|
||||
while (*p == ' ' || *p == '\t' || *p == '\014')
|
||||
p++;
|
||||
|
||||
/* Write some spaces before the line */
|
||||
strcpy(buf, " ");
|
||||
assert (strlen(buf) == 10);
|
||||
while (indent > 0) {
|
||||
if(indent < 10)
|
||||
buf[indent] = '\0';
|
||||
err = PyFile_WriteString(buf, f);
|
||||
if (err != 0)
|
||||
break;
|
||||
indent -= 10;
|
||||
}
|
||||
|
||||
if (err == 0)
|
||||
err = PyFile_WriteString(p, f);
|
||||
if (err == 0 && strchr(p, '\n') == NULL)
|
||||
err = PyFile_WriteString("\n", f);
|
||||
}
|
||||
fclose(xfp);
|
||||
return err;
|
||||
if (err == 0)
|
||||
err = PyFile_WriteString(p, f);
|
||||
if (err == 0 && strchr(p, '\n') == NULL)
|
||||
err = PyFile_WriteString("\n", f);
|
||||
}
|
||||
fclose(xfp);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int
|
||||
tb_displayline(PyObject *f, const char *filename, int lineno, const char *name)
|
||||
{
|
||||
int err = 0;
|
||||
char linebuf[2000];
|
||||
int err = 0;
|
||||
char linebuf[2000];
|
||||
|
||||
if (filename == NULL || name == NULL)
|
||||
return -1;
|
||||
/* This is needed by Emacs' compile command */
|
||||
if (filename == NULL || name == NULL)
|
||||
return -1;
|
||||
/* This is needed by Emacs' compile command */
|
||||
#define FMT " File \"%.500s\", line %d, in %.500s\n"
|
||||
PyOS_snprintf(linebuf, sizeof(linebuf), FMT, filename, lineno, name);
|
||||
err = PyFile_WriteString(linebuf, f);
|
||||
if (err != 0)
|
||||
return err;
|
||||
return _Py_DisplaySourceLine(f, filename, lineno, 4);
|
||||
PyOS_snprintf(linebuf, sizeof(linebuf), FMT, filename, lineno, name);
|
||||
err = PyFile_WriteString(linebuf, f);
|
||||
if (err != 0)
|
||||
return err;
|
||||
return _Py_DisplaySourceLine(f, filename, lineno, 4);
|
||||
}
|
||||
|
||||
static int
|
||||
tb_printinternal(PyTracebackObject *tb, PyObject *f, long limit)
|
||||
{
|
||||
int err = 0;
|
||||
long depth = 0;
|
||||
PyTracebackObject *tb1 = tb;
|
||||
while (tb1 != NULL) {
|
||||
depth++;
|
||||
tb1 = tb1->tb_next;
|
||||
}
|
||||
while (tb != NULL && err == 0) {
|
||||
if (depth <= limit) {
|
||||
err = tb_displayline(f,
|
||||
PyString_AsString(
|
||||
tb->tb_frame->f_code->co_filename),
|
||||
tb->tb_lineno,
|
||||
PyString_AsString(tb->tb_frame->f_code->co_name));
|
||||
}
|
||||
depth--;
|
||||
tb = tb->tb_next;
|
||||
if (err == 0)
|
||||
err = PyErr_CheckSignals();
|
||||
}
|
||||
return err;
|
||||
int err = 0;
|
||||
long depth = 0;
|
||||
PyTracebackObject *tb1 = tb;
|
||||
while (tb1 != NULL) {
|
||||
depth++;
|
||||
tb1 = tb1->tb_next;
|
||||
}
|
||||
while (tb != NULL && err == 0) {
|
||||
if (depth <= limit) {
|
||||
err = tb_displayline(f,
|
||||
PyString_AsString(
|
||||
tb->tb_frame->f_code->co_filename),
|
||||
tb->tb_lineno,
|
||||
PyString_AsString(tb->tb_frame->f_code->co_name));
|
||||
}
|
||||
depth--;
|
||||
tb = tb->tb_next;
|
||||
if (err == 0)
|
||||
err = PyErr_CheckSignals();
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
int
|
||||
PyTraceBack_Print(PyObject *v, PyObject *f)
|
||||
{
|
||||
int err;
|
||||
PyObject *limitv;
|
||||
long limit = 1000;
|
||||
if (v == NULL)
|
||||
return 0;
|
||||
if (!PyTraceBack_Check(v)) {
|
||||
PyErr_BadInternalCall();
|
||||
return -1;
|
||||
}
|
||||
limitv = PySys_GetObject("tracebacklimit");
|
||||
if (limitv && PyInt_Check(limitv)) {
|
||||
limit = PyInt_AsLong(limitv);
|
||||
if (limit <= 0)
|
||||
return 0;
|
||||
}
|
||||
err = PyFile_WriteString("Traceback (most recent call last):\n", f);
|
||||
if (!err)
|
||||
err = tb_printinternal((PyTracebackObject *)v, f, limit);
|
||||
return err;
|
||||
int err;
|
||||
PyObject *limitv;
|
||||
long limit = 1000;
|
||||
if (v == NULL)
|
||||
return 0;
|
||||
if (!PyTraceBack_Check(v)) {
|
||||
PyErr_BadInternalCall();
|
||||
return -1;
|
||||
}
|
||||
limitv = PySys_GetObject("tracebacklimit");
|
||||
if (limitv && PyInt_Check(limitv)) {
|
||||
limit = PyInt_AsLong(limitv);
|
||||
if (limit <= 0)
|
||||
return 0;
|
||||
}
|
||||
err = PyFile_WriteString("Traceback (most recent call last):\n", f);
|
||||
if (!err)
|
||||
err = tb_printinternal((PyTracebackObject *)v, f, limit);
|
||||
return err;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue