void close_keepers( void) #endif // HAVE_KEEPER_ATEXIT_DESINIT { int i; int const nbKeepers = GNbKeepers; // NOTE: imagine some keeper state N+1 currently holds a linda that uses another keeper N, and a _gc that will make use of it // when keeper N+1 is closed, object is GCed, linda operation is called, which attempts to acquire keeper N, whose Lua state no longer exists // in that case, the linda operation should do nothing. which means that these operations must check for keeper acquisition success GNbKeepers = 0; for( i = 0; i < nbKeepers; ++ i) { lua_State* L = GKeepers[i].L; GKeepers[i].L = NULL; lua_close( L); } for( i = 0; i < nbKeepers; ++ i) { MUTEX_FREE( &GKeepers[i].lock_); } if( GKeepers != NULL) { free( GKeepers); } GKeepers = NULL; }
void JKG_Stack_Destroy(jkg_stack_t *stack) // Clear up the stack { if (!stack->init) { // If not inited, ignore return; } MUTEX_FREE(stack); // Free the mutex/critical section memset(stack, 0, sizeof(jkg_stack_t)); // Clear the struct }
void JKG_Queue_Destroy(jkg_queue_t *queue) // Destroys a queue, same process as stack { if (!queue->init) { return; } MUTEX_FREE(queue); memset(queue, 0, sizeof(jkg_queue_t)); }
void close_keepers( void) #endif // HAVE_KEEPER_ATEXIT_DESINIT { int i; // 2-pass close, in case a keeper holds a reference to a linda bound to another keeoer for( i = 0; i < GNbKeepers; ++ i) { lua_State* L = GKeepers[i].L; GKeepers[i].L = 0; lua_close( L); } for( i = 0; i < GNbKeepers; ++ i) { MUTEX_FREE( &GKeepers[i].lock_); } if( GKeepers) free( GKeepers); GKeepers = NULL; GNbKeepers = 0; }
// called as __gc for the keepers array userdata void close_keepers( struct s_Universe* U, lua_State* L) { if( U->keepers != NULL) { int i; int nbKeepers = U->keepers->nb_keepers; // NOTE: imagine some keeper state N+1 currently holds a linda that uses another keeper N, and a _gc that will make use of it // when keeper N+1 is closed, object is GCed, linda operation is called, which attempts to acquire keeper N, whose Lua state no longer exists // in that case, the linda operation should do nothing. which means that these operations must check for keeper acquisition success // which is early-outed with a U->keepers->nbKeepers null-check U->keepers->nb_keepers = 0; for( i = 0; i < nbKeepers; ++ i) { lua_State* K = U->keepers->keeper_array[i].L; U->keepers->keeper_array[i].L = NULL; if( K != NULL) { lua_close( K); } else { // detected partial init: destroy only the mutexes that got initialized properly nbKeepers = i; } } for( i = 0; i < nbKeepers; ++ i) { MUTEX_FREE( &U->keepers->keeper_array[i].keeper_cs); } // free the keeper bookkeeping structure { void* allocUD; lua_Alloc allocF = lua_getallocf( L, &allocUD); allocF( allocUD, U->keepers, sizeof( struct s_Keepers) + (nbKeepers - 1) * sizeof(struct s_Keeper), 0); U->keepers = NULL; } } }
/*deallocate atomic polong inter*/ void atomic_free(atomic a) { MUTEX_FREE(&a->lock); free(a); }