提交 ea0dc132 authored 作者: Shane Bryldt's avatar Shane Bryldt

FS-10167: Rewrote the ks_pool allocator, no longer uses paging or internal block…

FS-10167: Rewrote the ks_pool allocator, no longer uses paging or internal block allocation, but still retains reference counting and auto cleanup callbacks, should be much more efficient now on windows than the original mmap approach, and all tests now run successfully!
上级 aaa26c6d
...@@ -312,7 +312,7 @@ KS_DECLARE(void) blade_connection_disconnect(blade_connection_t *bc) ...@@ -312,7 +312,7 @@ KS_DECLARE(void) blade_connection_disconnect(blade_connection_t *bc)
{ {
ks_assert(bc); ks_assert(bc);
if (bc->state != BLADE_CONNECTION_STATE_DETACH && bc->state != BLADE_CONNECTION_STATE_DISCONNECT) { if (bc->state != BLADE_CONNECTION_STATE_DETACH && bc->state != BLADE_CONNECTION_STATE_DISCONNECT && bc->state != BLADE_CONNECTION_STATE_CLEANUP) {
ks_log(KS_LOG_DEBUG, "Connection (%s) disconnecting\n", bc->id); ks_log(KS_LOG_DEBUG, "Connection (%s) disconnecting\n", bc->id);
blade_connection_state_set(bc, BLADE_CONNECTION_STATE_DETACH); blade_connection_state_set(bc, BLADE_CONNECTION_STATE_DETACH);
} }
......
...@@ -77,7 +77,7 @@ KS_DECLARE(ks_status_t) blade_datastore_create(blade_datastore_t **bdsP, ks_pool ...@@ -77,7 +77,7 @@ KS_DECLARE(ks_status_t) blade_datastore_create(blade_datastore_t **bdsP, ks_pool
ks_assert(bdsP); ks_assert(bdsP);
ks_assert(pool); ks_assert(pool);
ks_assert(tpool); //ks_assert(tpool);
bds = ks_pool_alloc(pool, sizeof(*bds)); bds = ks_pool_alloc(pool, sizeof(*bds));
bds->pool = pool; bds->pool = pool;
......
...@@ -869,7 +869,7 @@ blade_connection_state_hook_t blade_transport_wss_on_state_disconnect(blade_conn ...@@ -869,7 +869,7 @@ blade_connection_state_hook_t blade_transport_wss_on_state_disconnect(blade_conn
list_delete(&bt_wss->module->connected, bc); list_delete(&bt_wss->module->connected, bc);
if (bt_wss_init) blade_transport_wss_init_destroy(&bt_wss_init); if (bt_wss_init) blade_transport_wss_init_destroy(&bt_wss_init);
if (bt_wss) blade_transport_wss_destroy(&bt_wss); if (bt_wss) blade_transport_wss_destroy(&bt_wss); // @TODO: Scream at this very loudly until I feel better for it wasting 2 days to track down, and then fix the issue it's causing
return BLADE_CONNECTION_STATE_HOOK_SUCCESS; return BLADE_CONNECTION_STATE_HOOK_SUCCESS;
} }
...@@ -1092,6 +1092,8 @@ blade_connection_state_hook_t blade_transport_wss_on_state_attach_inbound(blade_ ...@@ -1092,6 +1092,8 @@ blade_connection_state_hook_t blade_transport_wss_on_state_attach_inbound(blade_
// behaviour to simply go as far as assigning a session to the connection and let the system handle the rest // behaviour to simply go as far as assigning a session to the connection and let the system handle the rest
if (json_req) cJSON_Delete(json_req); if (json_req) cJSON_Delete(json_req);
if (json_res) cJSON_Delete(json_res); if (json_res) cJSON_Delete(json_res);
return ret; return ret;
} }
...@@ -1223,6 +1225,7 @@ blade_connection_state_hook_t blade_transport_wss_on_state_attach_outbound(blade ...@@ -1223,6 +1225,7 @@ blade_connection_state_hook_t blade_transport_wss_on_state_attach_outbound(blade
done: done:
if (json_req) cJSON_Delete(json_req); if (json_req) cJSON_Delete(json_req);
if (json_res) cJSON_Delete(json_res); if (json_res) cJSON_Delete(json_res);
return ret; return ret;
} }
...@@ -1261,15 +1264,15 @@ blade_connection_state_hook_t blade_transport_wss_on_state_ready_outbound(blade_ ...@@ -1261,15 +1264,15 @@ blade_connection_state_hook_t blade_transport_wss_on_state_ready_outbound(blade_
if (condition == BLADE_CONNECTION_STATE_CONDITION_PRE) { if (condition == BLADE_CONNECTION_STATE_CONDITION_PRE) {
blade_session_t *bs = NULL; blade_session_t *bs = NULL;
cJSON *req = NULL; //cJSON *req = NULL;
ks_log(KS_LOG_DEBUG, "State Callback: %d\n", (int32_t)condition); ks_log(KS_LOG_DEBUG, "State Callback: %d\n", (int32_t)condition);
bs = blade_handle_sessions_get(blade_connection_handle_get(bc), blade_connection_session_get(bc)); bs = blade_handle_sessions_get(blade_connection_handle_get(bc), blade_connection_session_get(bc));
ks_assert(bs); ks_assert(bs);
blade_rpc_request_create(blade_connection_pool_get(bc), &req, NULL, NULL, "blade.test.echo"); //blade_rpc_request_create(blade_connection_pool_get(bc), &req, NULL, NULL, "blade.test.echo");
blade_session_send(bs, req, blade_test_echo_response_handler); //blade_session_send(bs, req, blade_test_echo_response_handler);
blade_session_read_unlock(bs); blade_session_read_unlock(bs);
} }
......
...@@ -159,6 +159,7 @@ KS_DECLARE(ks_status_t) blade_session_shutdown(blade_session_t *bs) ...@@ -159,6 +159,7 @@ KS_DECLARE(ks_status_t) blade_session_shutdown(blade_session_t *bs)
if (bs->state_thread) { if (bs->state_thread) {
bs->shutdown = KS_TRUE; bs->shutdown = KS_TRUE;
ks_thread_join(bs->state_thread); ks_thread_join(bs->state_thread);
printf("FREEING SESSION THREAD %p\n", (void *)bs->state_thread);
ks_pool_free(bs->pool, &bs->state_thread); ks_pool_free(bs->pool, &bs->state_thread);
bs->shutdown = KS_FALSE; bs->shutdown = KS_FALSE;
} }
......
...@@ -122,10 +122,10 @@ void on_blade_session_state_callback(blade_session_t *bs, blade_session_state_co ...@@ -122,10 +122,10 @@ void on_blade_session_state_callback(blade_session_t *bs, blade_session_state_co
if (condition == BLADE_SESSION_STATE_CONDITION_PRE) { if (condition == BLADE_SESSION_STATE_CONDITION_PRE) {
ks_log(KS_LOG_DEBUG, "Blade Session State Changed: %s, %d\n", blade_session_id_get(bs), state); ks_log(KS_LOG_DEBUG, "Blade Session State Changed: %s, %d\n", blade_session_id_get(bs), state);
if (state == BLADE_SESSION_STATE_READY) { if (state == BLADE_SESSION_STATE_READY) {
cJSON *req = NULL; //cJSON *req = NULL;
blade_rpc_request_create(blade_session_pool_get(bs), &req, NULL, NULL, "blade.chat.join"); //blade_rpc_request_create(blade_session_pool_get(bs), &req, NULL, NULL, "blade.chat.join");
blade_session_send(bs, req, on_blade_chat_join_response); //blade_session_send(bs, req, on_blade_chat_join_response);
cJSON_Delete(req); //cJSON_Delete(req);
} }
} }
} }
......
...@@ -72,13 +72,13 @@ int main(int argc, char **argv) ...@@ -72,13 +72,13 @@ int main(int argc, char **argv)
return EXIT_FAILURE; return EXIT_FAILURE;
} }
blade_module_chat_on_load(&mod_chat, bh); //blade_module_chat_on_load(&mod_chat, bh);
blade_module_chat_on_startup(mod_chat, config_blade); //blade_module_chat_on_startup(mod_chat, config_blade);
loop(bh); loop(bh);
blade_module_chat_on_shutdown(mod_chat); //blade_module_chat_on_shutdown(mod_chat);
blade_module_chat_on_unload(mod_chat); //blade_module_chat_on_unload(mod_chat);
blade_module_wss_on_shutdown(mod_wss); blade_module_wss_on_shutdown(mod_wss);
......
...@@ -72,16 +72,22 @@ _Check_return_ static __inline int _zstr(_In_opt_z_ const char *s) ...@@ -72,16 +72,22 @@ _Check_return_ static __inline int _zstr(_In_opt_z_ const char *s)
#define ks_set_string(_x, _y) ks_copy_string(_x, _y, sizeof(_x)) #define ks_set_string(_x, _y) ks_copy_string(_x, _y, sizeof(_x))
#define ks_safe_free(_x) if (_x) free(_x); _x = NULL #define ks_safe_free(_x) if (_x) free(_x); _x = NULL
#define end_of(_s) *(*_s == '\0' ? _s : _s + strlen(_s) - 1) #define end_of(_s) *(*_s == '\0' ? _s : _s + strlen(_s) - 1)
#define ks_test_flag(obj, flag) ((obj)->flags & flag)
#define ks_set_flag(obj, flag) (obj)->flags |= (flag)
#define ks_clear_flag(obj, flag) (obj)->flags &= ~(flag)
#define ks_recv(_h) ks_recv_event(_h, 0, NULL) #define ks_recv(_h) ks_recv_event(_h, 0, NULL)
#define ks_recv_timed(_h, _ms) ks_recv_event_timed(_h, _ms, 0, NULL) #define ks_recv_timed(_h, _ms) ks_recv_event_timed(_h, _ms, 0, NULL)
/*
* bitflag tools
*/
#define BIT_FLAG(x) (1 << (x))
#define BIT_SET(v,f) ((v) |= (f))
#define BIT_CLEAR(v,f) ((v) &= ~(f))
#define BIT_IS_SET(v,f) ((v) & (f))
#define BIT_TOGGLE(v,f) ((v) ^= (f))
KS_DECLARE(ks_status_t) ks_init(void); KS_DECLARE(ks_status_t) ks_init(void);
KS_DECLARE(ks_status_t) ks_shutdown(void); KS_DECLARE(ks_status_t) ks_shutdown(void);
KS_DECLARE(ks_pool_t *) ks_global_pool(void); KS_DECLARE(ks_pool_t *) ks_global_pool(void);
KS_DECLARE(ks_status_t) ks_global_set_cleanup(ks_pool_cleanup_fn_t fn, void *arg); KS_DECLARE(ks_status_t) ks_global_set_cleanup(ks_pool_cleanup_callback_t callback, void *arg);
KS_DECLARE(int) ks_vasprintf(char **ret, const char *fmt, va_list ap); KS_DECLARE(int) ks_vasprintf(char **ret, const char *fmt, va_list ap);
//KS_DECLARE_DATA extern ks_logger_t ks_logger; //KS_DECLARE_DATA extern ks_logger_t ks_logger;
......
...@@ -219,7 +219,7 @@ typedef struct { ...@@ -219,7 +219,7 @@ typedef struct {
char host[48]; char host[48];
} ks_sockaddr_t; } ks_sockaddr_t;
typedef void (*ks_pool_cleanup_fn_t) (ks_pool_t *mpool, void *ptr, void *arg, int type, ks_pool_cleanup_action_t action, ks_pool_cleanup_type_t ctype); typedef void (*ks_pool_cleanup_callback_t)(ks_pool_t *pool, void *ptr, void *arg, ks_pool_cleanup_action_t action, ks_pool_cleanup_type_t type);
typedef void (*ks_logger_t) (const char *file, const char *func, int line, int level, const char *fmt, ...); typedef void (*ks_logger_t) (const char *file, const char *func, int line, int level, const char *fmt, ...);
typedef void (*ks_listen_callback_t) (ks_socket_t server_sock, ks_socket_t client_sock, ks_sockaddr_t *addr, void *user_data); typedef void (*ks_listen_callback_t) (ks_socket_t server_sock, ks_socket_t client_sock, ks_sockaddr_t *addr, void *user_data);
......
...@@ -56,9 +56,9 @@ KS_DECLARE(void) ks_random_string(char *buf, uint16_t len, char *set) ...@@ -56,9 +56,9 @@ KS_DECLARE(void) ks_random_string(char *buf, uint16_t len, char *set)
} }
KS_DECLARE(ks_status_t) ks_global_set_cleanup(ks_pool_cleanup_fn_t fn, void *arg) KS_DECLARE(ks_status_t) ks_global_set_cleanup(ks_pool_cleanup_callback_t callback, void *arg)
{ {
return ks_pool_set_cleanup(ks_global_pool(), NULL, arg, 0, fn); return ks_pool_set_cleanup(ks_global_pool(), NULL, arg, callback);
} }
KS_DECLARE(ks_status_t) ks_init(void) KS_DECLARE(ks_status_t) ks_init(void)
......
...@@ -140,7 +140,7 @@ const float max_load_factor = 0.65f; ...@@ -140,7 +140,7 @@ const float max_load_factor = 0.65f;
/*****************************************************************************/ /*****************************************************************************/
static void ks_hash_cleanup(ks_pool_t *mpool, void *ptr, void *arg, int type, ks_pool_cleanup_action_t action, ks_pool_cleanup_type_t ctype) static void ks_hash_cleanup(ks_pool_t *mpool, void *ptr, void *arg, ks_pool_cleanup_action_t action, ks_pool_cleanup_type_t type)
{ {
//ks_hash_t *hash = (ks_hash_t *) ptr; //ks_hash_t *hash = (ks_hash_t *) ptr;
...@@ -270,7 +270,7 @@ ks_hash_create_ex(ks_hash_t **hp, unsigned int minsize, ...@@ -270,7 +270,7 @@ ks_hash_create_ex(ks_hash_t **hp, unsigned int minsize,
*hp = h; *hp = h;
ks_pool_set_cleanup(pool, h, NULL, 0, ks_hash_cleanup); ks_pool_set_cleanup(pool, h, NULL, ks_hash_cleanup);
return KS_STATUS_SUCCESS; return KS_STATUS_SUCCESS;
} }
......
...@@ -42,7 +42,7 @@ struct ks_mutex { ...@@ -42,7 +42,7 @@ struct ks_mutex {
uint8_t malloc; uint8_t malloc;
}; };
static void ks_mutex_cleanup(ks_pool_t *mpool, void *ptr, void *arg, int type, ks_pool_cleanup_action_t action, ks_pool_cleanup_type_t ctype) static void ks_mutex_cleanup(ks_pool_t *mpool, void *ptr, void *arg, ks_pool_cleanup_action_t action, ks_pool_cleanup_type_t type)
{ {
ks_mutex_t *mutex = (ks_mutex_t *) ptr; ks_mutex_t *mutex = (ks_mutex_t *) ptr;
...@@ -150,7 +150,7 @@ KS_DECLARE(ks_status_t) ks_mutex_create(ks_mutex_t **mutex, unsigned int flags, ...@@ -150,7 +150,7 @@ KS_DECLARE(ks_status_t) ks_mutex_create(ks_mutex_t **mutex, unsigned int flags,
status = KS_STATUS_SUCCESS; status = KS_STATUS_SUCCESS;
if (pool) { if (pool) {
ks_pool_set_cleanup(pool, check, NULL, 0, ks_mutex_cleanup); ks_pool_set_cleanup(pool, check, NULL, ks_mutex_cleanup);
} }
done: done:
...@@ -224,7 +224,7 @@ struct ks_cond { ...@@ -224,7 +224,7 @@ struct ks_cond {
uint8_t static_mutex; uint8_t static_mutex;
}; };
static void ks_cond_cleanup(ks_pool_t *mpool, void *ptr, void *arg, int type, ks_pool_cleanup_action_t action, ks_pool_cleanup_type_t ctype) static void ks_cond_cleanup(ks_pool_t *mpool, void *ptr, void *arg, ks_pool_cleanup_action_t action, ks_pool_cleanup_type_t type)
{ {
ks_cond_t *cond = (ks_cond_t *) ptr; ks_cond_t *cond = (ks_cond_t *) ptr;
...@@ -281,7 +281,7 @@ KS_DECLARE(ks_status_t) ks_cond_create_ex(ks_cond_t **cond, ks_pool_t *pool, ks_ ...@@ -281,7 +281,7 @@ KS_DECLARE(ks_status_t) ks_cond_create_ex(ks_cond_t **cond, ks_pool_t *pool, ks_
*cond = check; *cond = check;
status = KS_STATUS_SUCCESS; status = KS_STATUS_SUCCESS;
ks_pool_set_cleanup(pool, check, NULL, 0, ks_cond_cleanup); ks_pool_set_cleanup(pool, check, NULL, ks_cond_cleanup);
done: done:
return status; return status;
...@@ -436,7 +436,7 @@ struct ks_rwl { ...@@ -436,7 +436,7 @@ struct ks_rwl {
uint32_t wlc; uint32_t wlc;
}; };
static void ks_rwl_cleanup(ks_pool_t *mpool, void *ptr, void *arg, int type, ks_pool_cleanup_action_t action, ks_pool_cleanup_type_t ctype) static void ks_rwl_cleanup(ks_pool_t *mpool, void *ptr, void *arg, ks_pool_cleanup_action_t action, ks_pool_cleanup_type_t type)
{ {
#ifndef WIN32 #ifndef WIN32
ks_rwl_t *rwlock = (ks_rwl_t *) ptr; ks_rwl_t *rwlock = (ks_rwl_t *) ptr;
...@@ -494,7 +494,7 @@ KS_DECLARE(ks_status_t) ks_rwl_create(ks_rwl_t **rwlock, ks_pool_t *pool) ...@@ -494,7 +494,7 @@ KS_DECLARE(ks_status_t) ks_rwl_create(ks_rwl_t **rwlock, ks_pool_t *pool)
*rwlock = check; *rwlock = check;
status = KS_STATUS_SUCCESS; status = KS_STATUS_SUCCESS;
ks_pool_set_cleanup(pool, check, NULL, 0, ks_rwl_cleanup); ks_pool_set_cleanup(pool, check, NULL, ks_rwl_cleanup);
done: done:
return status; return status;
} }
......
差异被折叠。
...@@ -56,12 +56,12 @@ struct ks_q_s { ...@@ -56,12 +56,12 @@ struct ks_q_s {
uint8_t active; uint8_t active;
}; };
static void ks_q_cleanup(ks_pool_t *mpool, void *ptr, void *arg, int type, ks_pool_cleanup_action_t action, ks_pool_cleanup_type_t ctype) static void ks_q_cleanup(ks_pool_t *mpool, void *ptr, void *arg, ks_pool_cleanup_action_t action, ks_pool_cleanup_type_t type)
{ {
ks_q_t *q = (ks_q_t *) ptr; ks_q_t *q = (ks_q_t *) ptr;
ks_qnode_t *np, *fp; ks_qnode_t *np, *fp;
if (ctype == KS_MPCL_GLOBAL_FREE) { if (type == KS_MPCL_GLOBAL_FREE) {
return; return;
} }
...@@ -202,7 +202,7 @@ KS_DECLARE(ks_status_t) ks_q_create(ks_q_t **qP, ks_pool_t *pool, ks_size_t maxl ...@@ -202,7 +202,7 @@ KS_DECLARE(ks_status_t) ks_q_create(ks_q_t **qP, ks_pool_t *pool, ks_size_t maxl
q->maxlen = maxlen; q->maxlen = maxlen;
q->active = 1; q->active = 1;
ks_pool_set_cleanup(pool, q, NULL, 0, ks_q_cleanup); ks_pool_set_cleanup(pool, q, NULL, ks_q_cleanup);
*qP = q; *qP = q;
......
...@@ -79,7 +79,7 @@ void ks_thread_override_default_stacksize(size_t size) ...@@ -79,7 +79,7 @@ void ks_thread_override_default_stacksize(size_t size)
thread_default_stacksize = size; thread_default_stacksize = size;
} }
static void ks_thread_cleanup(ks_pool_t *mpool, void *ptr, void *arg, int type, ks_pool_cleanup_action_t action, ks_pool_cleanup_type_t ctype) static void ks_thread_cleanup(ks_pool_t *mpool, void *ptr, void *arg, ks_pool_cleanup_action_t action, ks_pool_cleanup_type_t type)
{ {
ks_thread_t *thread = (ks_thread_t *) ptr; ks_thread_t *thread = (ks_thread_t *) ptr;
...@@ -309,7 +309,7 @@ KS_DECLARE(ks_status_t) ks_thread_create_ex(ks_thread_t **rthread, ks_thread_fun ...@@ -309,7 +309,7 @@ KS_DECLARE(ks_status_t) ks_thread_create_ex(ks_thread_t **rthread, ks_thread_fun
} }
*rthread = thread; *rthread = thread;
ks_pool_set_cleanup(pool, thread, NULL, 0, ks_thread_cleanup); ks_pool_set_cleanup(pool, thread, NULL, ks_thread_cleanup);
} }
return status; return status;
......
...@@ -22,7 +22,7 @@ int test1(void) ...@@ -22,7 +22,7 @@ int test1(void)
ks_hash_iterator_t *itt; ks_hash_iterator_t *itt;
ks_hash_write_lock(hash); ks_hash_write_lock(hash);
for (itt = ks_hash_first(hash, KS_UNLOCKED); itt; itt = ks_hash_next(&itt)) { for (itt = ks_hash_first(hash, KS_UNLOCKED); itt; ) {
const void *key; const void *key;
void *val; void *val;
...@@ -31,6 +31,7 @@ int test1(void) ...@@ -31,6 +31,7 @@ int test1(void)
printf("%s=%s\n", (char *)key, (char *)val); printf("%s=%s\n", (char *)key, (char *)val);
sum2 += atoi(val); sum2 += atoi(val);
itt = ks_hash_next(&itt);
ks_hash_remove(hash, (char *)key); ks_hash_remove(hash, (char *)key);
} }
ks_hash_write_unlock(hash); ks_hash_write_unlock(hash);
...@@ -95,13 +96,15 @@ int test2(void) ...@@ -95,13 +96,15 @@ int test2(void)
ks_sleep(x * 1000000); ks_sleep(x * 1000000);
ks_hash_write_lock(hash); ks_hash_write_lock(hash);
for (itt = ks_hash_first(hash, KS_UNLOCKED); itt; itt = ks_hash_next(&itt)) { for (itt = ks_hash_first(hash, KS_UNLOCKED); itt; ) {
const void *key; const void *key;
void *val; void *val;
ks_hash_this(itt, &key, NULL, &val); ks_hash_this(itt, &key, NULL, &val);
printf("DEL %s=%s\n", (char *)key, (char *)val); printf("DEL %s=%s\n", (char *)key, (char *)val);
itt = ks_hash_next(&itt);
ks_hash_remove(hash, (char *)key); ks_hash_remove(hash, (char *)key);
} }
ks_hash_write_unlock(hash); ks_hash_write_unlock(hash);
......
...@@ -18,7 +18,7 @@ struct foo { ...@@ -18,7 +18,7 @@ struct foo {
}; };
void cleanup(ks_pool_t *mpool, void *ptr, void *arg, int type, ks_pool_cleanup_action_t action, ks_pool_cleanup_type_t ctype) void cleanup(ks_pool_t *mpool, void *ptr, void *arg, ks_pool_cleanup_action_t action, ks_pool_cleanup_type_t type)
{ {
struct foo *foo = (struct foo *) ptr; struct foo *foo = (struct foo *) ptr;
...@@ -158,7 +158,7 @@ int main(int argc, char **argv) ...@@ -158,7 +158,7 @@ int main(int argc, char **argv)
foo->x = 12; foo->x = 12;
foo->str = strdup("This is a test 1234 abcd; This will be called on explicit free\n"); foo->str = strdup("This is a test 1234 abcd; This will be called on explicit free\n");
ks_pool_set_cleanup(pool, foo, NULL, 0, cleanup); ks_pool_set_cleanup(pool, foo, NULL, cleanup);
printf("FREE OBJ:\n"); printf("FREE OBJ:\n");
...@@ -184,7 +184,7 @@ int main(int argc, char **argv) ...@@ -184,7 +184,7 @@ int main(int argc, char **argv)
foo->x = 12; foo->x = 12;
foo->str = strdup("This is a second test 1234 abcd; This will be called on pool clear/destroy\n"); foo->str = strdup("This is a second test 1234 abcd; This will be called on pool clear/destroy\n");
ks_pool_set_cleanup(pool, foo, NULL, 0, cleanup); ks_pool_set_cleanup(pool, foo, NULL, cleanup);
printf("ALLOC OBJ3: %p\n", (void *)pool); printf("ALLOC OBJ3: %p\n", (void *)pool);
...@@ -202,7 +202,7 @@ int main(int argc, char **argv) ...@@ -202,7 +202,7 @@ int main(int argc, char **argv)
printf("CLEANUP: %p\n", (void *)pool); printf("CLEANUP: %p\n", (void *)pool);
foo->x = 12; foo->x = 12;
foo->str = strdup("This is a third test 1234 abcd; This will be called on pool clear/destroy\n"); foo->str = strdup("This is a third test 1234 abcd; This will be called on pool clear/destroy\n");
ks_pool_set_cleanup(pool, foo, NULL, 0, cleanup); ks_pool_set_cleanup(pool, foo, NULL, cleanup);
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论