Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit fa297ef

Browse files
Use a linked list.
1 parent c4d7d32 commit fa297ef

1 file changed

Lines changed: 85 additions & 52 deletions

File tree

Modules/_xxsubinterpretersmodule.c

Lines changed: 85 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -491,83 +491,116 @@ _run_in_interpreter(PyInterpreterState *interp,
491491

492492
/* "owned" interpreters *****************************************************/
493493

494-
typedef _Py_hashtable_t owned_ids;
495-
496-
static Py_uhash_t
497-
hash_int64(const void *key)
498-
{
499-
#if sizeof(int64_t) <= sizeof(Py_uhash_t)
500-
return (Py_uhash_t)key;
501-
#else
502-
int64_t val = *(int64_t *)key;
503-
return val % sizeof(Py_uhash_t);
504-
#endif
505-
}
494+
struct owned_id {
495+
int64_t id;
496+
struct owned_id *next;
497+
};
506498

507-
static int
508-
compare_int64(const void *key1, const void *key2)
509-
{
510-
#if sizeof(int64_t) <= sizeof(Py_uhash_t)
511-
return (int64_t)key1 == (int64_t)key2;
512-
#else
513-
int64_t val1 = *(int64_t *)key1;
514-
int64_t val2 = *(int64_t *)key2;
515-
return val1 == val2;
516-
#endif
517-
}
499+
typedef struct {
500+
PyMutex mutex;
501+
struct owned_id *head;
502+
Py_ssize_t count;
503+
} owned_ids;
518504

519505
static int
520506
init_owned(owned_ids *owned)
521507
{
522-
_Py_hashtable_allocator_t alloc = (_Py_hashtable_allocator_t){
523-
.malloc = PyMem_RawMalloc,
524-
.free = PyMem_RawFree,
525-
};
526-
_globals.owned = _Py_hashtable_new_full(
527-
hash_int64, compare_int64, NULL, NULL, &alloc);
528-
if (_globals.owned == NULL) {
529-
PyErr_NoMemory();
530-
return -1;
531-
}
532508
return 0;
533509
}
534510

535511
static void
536512
clear_owned(owned_ids *owned)
537513
{
538-
_Py_hashtable_destroy(owned);
514+
PyMutex_Lock(&owned->mutex);
515+
struct owned_id *cur = owned->head;
516+
Py_ssize_t count = 0;
517+
while (cur != NULL) {
518+
struct owned_id *next = cur->next;
519+
PyMem_RawFree(cur);
520+
cur = next;
521+
count += 1;
522+
}
523+
assert(count == owned->count);
524+
owned->head = NULL;
525+
owned->count = 0;
526+
PyMutex_Unlock(&owned->mutex);
539527
}
540528

541-
static int
529+
static struct owned_id *
530+
_find_owned(owned_ids *owned, int64_t interpid, struct owned_id **p_prev)
531+
{
532+
// The caller must manage the lock.
533+
if (owned->head == NULL) {
534+
return NULL;
535+
}
536+
537+
struct owned_id *prev = NULL;
538+
struct owned_id *cur = owned->head;
539+
while (cur != NULL) {
540+
if (cur->id == interpid) {
541+
break;
542+
}
543+
prev = cur;
544+
cur = cur->next;
545+
}
546+
if (cur == NULL) {
547+
return NULL;
548+
}
549+
550+
if (p_prev != NULL) {
551+
*p_prev = prev;
552+
}
553+
return cur;
554+
}
555+
556+
static void
542557
add_owned(owned_ids *owned, PyInterpreterState *interp)
543558
{
559+
PyMutex_Lock(&owned->mutex);
544560
int64_t id = PyInterpreterState_GetID(interp);
545-
#if sizeof(int64_t) <= sizeof(Py_uhash_t)
546-
return _Py_hashtable_set(owned_ids, (const void *)id, 1);
547-
#else
548-
assert(0);
549-
#endif
561+
struct owned_id *new = PyMem_RawMalloc(sizeof(struct owned_id));
562+
assert(new != NULL);
563+
new->id = id;
564+
new->next = owned->head;
565+
owned->head = new;
566+
owned->count += 1;
567+
PyMutex_Unlock(&owned->mutex);
550568
}
551569

552570
static void
553571
drop_owned(owned_ids *owned, int64_t interpid)
554572
{
555-
#if sizeof(int64_t) <= sizeof(Py_uhash_t)
556-
_Py_hashtable_steal(owned_ids, (const void *)id);
557-
#else
558-
assert(0);
559-
#endif
573+
PyMutex_Lock(&owned->mutex);
574+
575+
struct owned_id *prev;
576+
struct owned_id *found = _find_owned(owned, interpid, &prev);
577+
if (found != NULL) {
578+
if (prev == NULL) {
579+
assert(found == owned->head);
580+
owned->head = found->next;
581+
}
582+
else {
583+
assert(found != owned->head);
584+
prev->next = found->next;
585+
}
586+
PyMem_RawFree(found);
587+
owned->count -= 1;
588+
}
589+
590+
PyMutex_Unlock(&owned->mutex);
560591
}
561592

562593
static int
563594
is_owned(owned_ids *owned, PyInterpreterState *interp)
564595
{
565-
int64_t id = PyInterpreterState_GetID(interp);
566-
#if sizeof(int64_t) <= sizeof(Py_uhash_t)
567-
return _Py_hashtable_get_entry(owned_ids, (const void *)id) != NULL;
568-
#else
569-
assert(0);
570-
#endif
596+
int64_t interpid = PyInterpreterState_GetID(interp);
597+
PyMutex_Lock(&owned->mutex);
598+
599+
struct owned_id *found = _find_owned(owned, interpid, NULL);
600+
int res = found != NULL;
601+
602+
PyMutex_Unlock(&owned->mutex);
603+
return res;
571604
}
572605

573606

@@ -579,7 +612,7 @@ is_owned(owned_ids *owned, PyInterpreterState *interp)
579612
static struct globals {
580613
PyMutex mutex;
581614
int module_count;
582-
_Py_hashtable_t *owned;
615+
owned_ids owned;
583616
} _globals = {0};
584617

585618
static int

0 commit comments

Comments
 (0)