Ignore:
Timestamp:
Mar 19, 2014, 11:31:01 PM (11 years ago)
Author:
dmik
Message:

python: Merge vendor 2.7.6 to trunk.

Location:
python/trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • python/trunk

  • python/trunk/Python/thread_nt.h

    r2 r391  
    1111
    1212typedef struct NRMUTEX {
    13         LONG   owned ;
    14         DWORD  thread_id ;
    15         HANDLE hevent ;
     13    LONG   owned ;
     14    DWORD  thread_id ;
     15    HANDLE hevent ;
    1616} NRMUTEX, *PNRMUTEX ;
    1717
     
    2020InitializeNonRecursiveMutex(PNRMUTEX mutex)
    2121{
    22         mutex->owned = -1 ;  /* No threads have entered NonRecursiveMutex */
    23         mutex->thread_id = 0 ;
    24         mutex->hevent = CreateEvent(NULL, FALSE, FALSE, NULL) ;
    25         return mutex->hevent != NULL ;  /* TRUE if the mutex is created */
     22    mutex->owned = -1 ;  /* No threads have entered NonRecursiveMutex */
     23    mutex->thread_id = 0 ;
     24    mutex->hevent = CreateEvent(NULL, FALSE, FALSE, NULL) ;
     25    return mutex->hevent != NULL ;      /* TRUE if the mutex is created */
    2626}
    2727
     
    2929DeleteNonRecursiveMutex(PNRMUTEX mutex)
    3030{
    31         /* No in-use check */
    32         CloseHandle(mutex->hevent) ;
    33         mutex->hevent = NULL ; /* Just in case */
     31    /* No in-use check */
     32    CloseHandle(mutex->hevent) ;
     33    mutex->hevent = NULL ; /* Just in case */
    3434}
    3535
     
    3737EnterNonRecursiveMutex(PNRMUTEX mutex, BOOL wait)
    3838{
    39         /* Assume that the thread waits successfully */
    40         DWORD ret ;
    41 
    42         /* InterlockedIncrement(&mutex->owned) == 0 means that no thread currently owns the mutex */
    43         if (!wait)
    44         {
    45                 if (InterlockedCompareExchange(&mutex->owned, 0, -1) != -1)
    46                         return WAIT_TIMEOUT ;
    47                 ret = WAIT_OBJECT_0 ;
    48         }
    49         else
    50                 ret = InterlockedIncrement(&mutex->owned) ?
    51                         /* Some thread owns the mutex, let's wait... */
    52                         WaitForSingleObject(mutex->hevent, INFINITE) : WAIT_OBJECT_0 ;
    53 
    54         mutex->thread_id = GetCurrentThreadId() ; /* We own it */
    55         return ret ;
     39    /* Assume that the thread waits successfully */
     40    DWORD ret ;
     41
     42    /* InterlockedIncrement(&mutex->owned) == 0 means that no thread currently owns the mutex */
     43    if (!wait)
     44    {
     45        if (InterlockedCompareExchange(&mutex->owned, 0, -1) != -1)
     46            return WAIT_TIMEOUT ;
     47        ret = WAIT_OBJECT_0 ;
     48    }
     49    else
     50        ret = InterlockedIncrement(&mutex->owned) ?
     51            /* Some thread owns the mutex, let's wait... */
     52            WaitForSingleObject(mutex->hevent, INFINITE) : WAIT_OBJECT_0 ;
     53
     54    mutex->thread_id = GetCurrentThreadId() ; /* We own it */
     55    return ret ;
    5656}
    5757
     
    5959LeaveNonRecursiveMutex(PNRMUTEX mutex)
    6060{
    61         /* We don't own the mutex */
    62         mutex->thread_id = 0 ;
    63         return
    64                 InterlockedDecrement(&mutex->owned) < 0 ||
    65                 SetEvent(mutex->hevent) ; /* Other threads are waiting, wake one on them up */
     61    /* We don't own the mutex */
     62    mutex->thread_id = 0 ;
     63    return
     64        InterlockedDecrement(&mutex->owned) < 0 ||
     65        SetEvent(mutex->hevent) ; /* Other threads are waiting, wake one on them up */
    6666}
    6767
     
    6969AllocNonRecursiveMutex(void)
    7070{
    71         PNRMUTEX mutex = (PNRMUTEX)malloc(sizeof(NRMUTEX)) ;
    72         if (mutex && !InitializeNonRecursiveMutex(mutex))
    73         {
    74                 free(mutex) ;
    75                 mutex = NULL ;
    76         }
    77         return mutex ;
     71    PNRMUTEX mutex = (PNRMUTEX)malloc(sizeof(NRMUTEX)) ;
     72    if (mutex && !InitializeNonRecursiveMutex(mutex))
     73    {
     74        free(mutex) ;
     75        mutex = NULL ;
     76    }
     77    return mutex ;
    7878}
    7979
     
    8181FreeNonRecursiveMutex(PNRMUTEX mutex)
    8282{
    83         if (mutex)
    84         {
    85                 DeleteNonRecursiveMutex(mutex) ;
    86                 free(mutex) ;
    87         }
     83    if (mutex)
     84    {
     85        DeleteNonRecursiveMutex(mutex) ;
     86        free(mutex) ;
     87    }
    8888}
    8989
     
    103103
    104104typedef struct {
    105         void (*func)(void*);
    106         void *arg;
    107         long id;
    108         HANDLE done;
     105    void (*func)(void*);
     106    void *arg;
    109107} callobj;
    110108
    111 static int
     109/* thunker to call adapt between the function type used by the system's
     110thread start function and the internally used one. */
     111#if defined(MS_WINCE)
     112static DWORD WINAPI
     113#else
     114static unsigned __stdcall
     115#endif
    112116bootstrap(void *call)
    113117{
    114         callobj *obj = (callobj*)call;
    115         /* copy callobj since other thread might free it before we're done */
    116         void (*func)(void*) = obj->func;
    117         void *arg = obj->arg;
    118 
    119         obj->id = PyThread_get_thread_ident();
    120         ReleaseSemaphore(obj->done, 1, NULL);
    121         func(arg);
    122         return 0;
     118    callobj *obj = (callobj*)call;
     119    void (*func)(void*) = obj->func;
     120    void *arg = obj->arg;
     121    HeapFree(GetProcessHeap(), 0, obj);
     122    func(arg);
     123    return 0;
    123124}
    124125
     
    126127PyThread_start_new_thread(void (*func)(void *), void *arg)
    127128{
    128         Py_uintptr_t rv;
    129         callobj obj;
    130 
    131         dprintf(("%ld: PyThread_start_new_thread called\n",
    132                  PyThread_get_thread_ident()));
    133         if (!initialized)
    134                 PyThread_init_thread();
    135 
    136         obj.id = -1;    /* guilty until proved innocent */
    137         obj.func = func;
    138         obj.arg = arg;
    139         obj.done = CreateSemaphore(NULL, 0, 1, NULL);
    140         if (obj.done == NULL)
    141                 return -1;
    142 
    143         rv = _beginthread(bootstrap,
    144                           Py_SAFE_DOWNCAST(_pythread_stacksize,
    145                                            Py_ssize_t, int),
    146                           &obj);
    147         if (rv == (Py_uintptr_t)-1) {
    148                 /* I've seen errno == EAGAIN here, which means "there are
    149                  * too many threads".
    150                  */
    151                 dprintf(("%ld: PyThread_start_new_thread failed: %p errno %d\n",
    152                          PyThread_get_thread_ident(), (void*)rv, errno));
    153                 obj.id = -1;
    154         }
    155         else {
    156                 dprintf(("%ld: PyThread_start_new_thread succeeded: %p\n",
    157                          PyThread_get_thread_ident(), (void*)rv));
    158                 /* wait for thread to initialize, so we can get its id */
    159                 WaitForSingleObject(obj.done, INFINITE);
    160                 assert(obj.id != -1);
    161         }
    162         CloseHandle((HANDLE)obj.done);
    163         return obj.id;
     129    HANDLE hThread;
     130    unsigned threadID;
     131    callobj *obj;
     132
     133    dprintf(("%ld: PyThread_start_new_thread called\n",
     134             PyThread_get_thread_ident()));
     135    if (!initialized)
     136        PyThread_init_thread();
     137
     138    obj = (callobj*)HeapAlloc(GetProcessHeap(), 0, sizeof(*obj));
     139    if (!obj)
     140        return -1;
     141    obj->func = func;
     142    obj->arg = arg;
     143#if defined(MS_WINCE)
     144    hThread = CreateThread(NULL,
     145                           Py_SAFE_DOWNCAST(_pythread_stacksize, Py_ssize_t, SIZE_T),
     146                           bootstrap, obj, 0, &threadID);
     147#else
     148    hThread = (HANDLE)_beginthreadex(0,
     149                      Py_SAFE_DOWNCAST(_pythread_stacksize,
     150                                       Py_ssize_t, unsigned int),
     151                      bootstrap, obj,
     152                      0, &threadID);
     153#endif
     154    if (hThread == 0) {
     155#if defined(MS_WINCE)
     156        /* Save error in variable, to prevent PyThread_get_thread_ident
     157           from clobbering it. */
     158        unsigned e = GetLastError();
     159        dprintf(("%ld: PyThread_start_new_thread failed, win32 error code %u\n",
     160                 PyThread_get_thread_ident(), e));
     161#else
     162        /* I've seen errno == EAGAIN here, which means "there are
     163         * too many threads".
     164         */
     165        int e = errno;
     166        dprintf(("%ld: PyThread_start_new_thread failed, errno %d\n",
     167                 PyThread_get_thread_ident(), e));
     168#endif
     169        threadID = (unsigned)-1;
     170        HeapFree(GetProcessHeap(), 0, obj);
     171    }
     172    else {
     173        dprintf(("%ld: PyThread_start_new_thread succeeded: %p\n",
     174                 PyThread_get_thread_ident(), (void*)hThread));
     175        CloseHandle(hThread);
     176    }
     177    return (long) threadID;
    164178}
    165179
     
    171185PyThread_get_thread_ident(void)
    172186{
    173         if (!initialized)
    174                 PyThread_init_thread();
    175 
    176         return GetCurrentThreadId();
    177 }
    178 
    179 static void
    180 do_PyThread_exit_thread(int no_cleanup)
    181 {
    182         dprintf(("%ld: PyThread_exit_thread called\n", PyThread_get_thread_ident()));
    183         if (!initialized)
    184                 if (no_cleanup)
    185                         _exit(0);
    186                 else
    187                         exit(0);
    188         _endthread();
     187    if (!initialized)
     188        PyThread_init_thread();
     189
     190    return GetCurrentThreadId();
    189191}
    190192
     
    192194PyThread_exit_thread(void)
    193195{
    194         do_PyThread_exit_thread(0);
    195 }
    196 
    197 void
    198 PyThread__exit_thread(void)
    199 {
    200         do_PyThread_exit_thread(1);
    201 }
    202 
    203 #ifndef NO_EXIT_PROG
    204 static void
    205 do_PyThread_exit_prog(int status, int no_cleanup)
    206 {
    207         dprintf(("PyThread_exit_prog(%d) called\n", status));
    208         if (!initialized)
    209                 if (no_cleanup)
    210                         _exit(status);
    211                 else
    212                         exit(status);
    213 }
    214 
    215 void
    216 PyThread_exit_prog(int status)
    217 {
    218         do_PyThread_exit_prog(status, 0);
    219 }
    220 
    221 void
    222 PyThread__exit_prog(int status)
    223 {
    224         do_PyThread_exit_prog(status, 1);
    225 }
    226 #endif /* NO_EXIT_PROG */
     196    dprintf(("%ld: PyThread_exit_thread called\n", PyThread_get_thread_ident()));
     197    if (!initialized)
     198        exit(0);
     199#if defined(MS_WINCE)
     200    ExitThread(0);
     201#else
     202    _endthreadex(0);
     203#endif
     204}
    227205
    228206/*
     
    234212PyThread_allocate_lock(void)
    235213{
    236         PNRMUTEX aLock;
    237 
    238         dprintf(("PyThread_allocate_lock called\n"));
    239         if (!initialized)
    240                 PyThread_init_thread();
    241 
    242         aLock = AllocNonRecursiveMutex() ;
    243 
    244         dprintf(("%ld: PyThread_allocate_lock() -> %p\n", PyThread_get_thread_ident(), aLock));
    245 
    246         return (PyThread_type_lock) aLock;
     214    PNRMUTEX aLock;
     215
     216    dprintf(("PyThread_allocate_lock called\n"));
     217    if (!initialized)
     218        PyThread_init_thread();
     219
     220    aLock = AllocNonRecursiveMutex() ;
     221
     222    dprintf(("%ld: PyThread_allocate_lock() -> %p\n", PyThread_get_thread_ident(), aLock));
     223
     224    return (PyThread_type_lock) aLock;
    247225}
    248226
     
    250228PyThread_free_lock(PyThread_type_lock aLock)
    251229{
    252         dprintf(("%ld: PyThread_free_lock(%p) called\n", PyThread_get_thread_ident(),aLock));
    253 
    254         FreeNonRecursiveMutex(aLock) ;
     230    dprintf(("%ld: PyThread_free_lock(%p) called\n", PyThread_get_thread_ident(),aLock));
     231
     232    FreeNonRecursiveMutex(aLock) ;
    255233}
    256234
     
    264242PyThread_acquire_lock(PyThread_type_lock aLock, int waitflag)
    265243{
    266         int success ;
    267 
    268         dprintf(("%ld: PyThread_acquire_lock(%p, %d) called\n", PyThread_get_thread_ident(),aLock, waitflag));
    269 
    270         success = aLock && EnterNonRecursiveMutex((PNRMUTEX) aLock, (waitflag ? INFINITE : 0)) == WAIT_OBJECT_0 ;
    271 
    272         dprintf(("%ld: PyThread_acquire_lock(%p, %d) -> %d\n", PyThread_get_thread_ident(),aLock, waitflag, success));
    273 
    274         return success;
     244    int success ;
     245
     246    dprintf(("%ld: PyThread_acquire_lock(%p, %d) called\n", PyThread_get_thread_ident(),aLock, waitflag));
     247
     248    success = aLock && EnterNonRecursiveMutex((PNRMUTEX) aLock, (waitflag ? INFINITE : 0)) == WAIT_OBJECT_0 ;
     249
     250    dprintf(("%ld: PyThread_acquire_lock(%p, %d) -> %d\n", PyThread_get_thread_ident(),aLock, waitflag, success));
     251
     252    return success;
    275253}
    276254
     
    278256PyThread_release_lock(PyThread_type_lock aLock)
    279257{
    280         dprintf(("%ld: PyThread_release_lock(%p) called\n", PyThread_get_thread_ident(),aLock));
    281 
    282         if (!(aLock && LeaveNonRecursiveMutex((PNRMUTEX) aLock)))
    283                 dprintf(("%ld: Could not PyThread_release_lock(%p) error: %ld\n", PyThread_get_thread_ident(), aLock, GetLastError()));
     258    dprintf(("%ld: PyThread_release_lock(%p) called\n", PyThread_get_thread_ident(),aLock));
     259
     260    if (!(aLock && LeaveNonRecursiveMutex((PNRMUTEX) aLock)))
     261        dprintf(("%ld: Could not PyThread_release_lock(%p) error: %ld\n", PyThread_get_thread_ident(), aLock, GetLastError()));
    284262}
    285263
    286264/* minimum/maximum thread stack sizes supported */
    287 #define THREAD_MIN_STACKSIZE    0x8000          /* 32kB */
    288 #define THREAD_MAX_STACKSIZE    0x10000000      /* 256MB */
     265#define THREAD_MIN_STACKSIZE    0x8000          /* 32kB */
     266#define THREAD_MAX_STACKSIZE    0x10000000      /* 256MB */
    289267
    290268/* set the thread stack size.
     
    294272_pythread_nt_set_stacksize(size_t size)
    295273{
    296         /* set to default */
    297         if (size == 0) {
    298                 _pythread_stacksize = 0;
    299                 return 0;
    300         }
    301 
    302         /* valid range? */
    303         if (size >= THREAD_MIN_STACKSIZE && size < THREAD_MAX_STACKSIZE) {
    304                 _pythread_stacksize = size;
    305                 return 0;
    306         }
    307 
    308         return -1;
    309 }
    310 
    311 #define THREAD_SET_STACKSIZE(x) _pythread_nt_set_stacksize(x)
     274    /* set to default */
     275    if (size == 0) {
     276        _pythread_stacksize = 0;
     277        return 0;
     278    }
     279
     280    /* valid range? */
     281    if (size >= THREAD_MIN_STACKSIZE && size < THREAD_MAX_STACKSIZE) {
     282        _pythread_stacksize = size;
     283        return 0;
     284    }
     285
     286    return -1;
     287}
     288
     289#define THREAD_SET_STACKSIZE(x) _pythread_nt_set_stacksize(x)
     290
     291
     292/* use native Windows TLS functions */
     293#define Py_HAVE_NATIVE_TLS
     294
     295#ifdef Py_HAVE_NATIVE_TLS
     296int
     297PyThread_create_key(void)
     298{
     299    return (int) TlsAlloc();
     300}
     301
     302void
     303PyThread_delete_key(int key)
     304{
     305    TlsFree(key);
     306}
     307
     308/* We must be careful to emulate the strange semantics implemented in thread.c,
     309 * where the value is only set if it hasn't been set before.
     310 */
     311int
     312PyThread_set_key_value(int key, void *value)
     313{
     314    BOOL ok;
     315    void *oldvalue;
     316
     317    assert(value != NULL);
     318    oldvalue = TlsGetValue(key);
     319    if (oldvalue != NULL)
     320        /* ignore value if already set */
     321        return 0;
     322    ok = TlsSetValue(key, value);
     323    if (!ok)
     324        return -1;
     325    return 0;
     326}
     327
     328void *
     329PyThread_get_key_value(int key)
     330{
     331    /* because TLS is used in the Py_END_ALLOW_THREAD macro,
     332     * it is necessary to preserve the windows error state, because
     333     * it is assumed to be preserved across the call to the macro.
     334     * Ideally, the macro should be fixed, but it is simpler to
     335     * do it here.
     336     */
     337    DWORD error = GetLastError();
     338    void *result = TlsGetValue(key);
     339    SetLastError(error);
     340    return result;
     341}
     342
     343void
     344PyThread_delete_key_value(int key)
     345{
     346    /* NULL is used as "key missing", and it is also the default
     347     * given by TlsGetValue() if nothing has been set yet.
     348     */
     349    TlsSetValue(key, NULL);
     350}
     351
     352/* reinitialization of TLS is not necessary after fork when using
     353 * the native TLS functions.  And forking isn't supported on Windows either.
     354 */
     355void
     356PyThread_ReInitTLS(void)
     357{}
     358
     359#endif
Note: See TracChangeset for help on using the changeset viewer.