#include "precompile.h" #include #include "shm_table.h" #include "shm_mem.h" #include "memutil.h" #include "list.h" #include "hash.h" #include #define HTABLE_SLOT_NUM 1023 typedef struct shm_table_entry_t { struct hlist_node entry; char *key; void *data; int len; }shm_table_entry_t; typedef struct shm_table_core { struct hlist_head hlist[HTABLE_SLOT_NUM]; int cnt; }shm_table_core; struct shm_table_t { shm_table_core *core; HANDLE hMutex; int first; }; static HANDLE create_mutex(int shmkey) { char name[32]; sprintf(name, "shm_table%08d", shmkey); return CreateMutexA(NULL, FALSE, name); } static shm_table_entry_t *find_entry(struct hlist_head *phead, const char *key) { shm_table_entry_t *tpos; struct hlist_node *pos; hlist_for_each_entry(tpos, pos, phead, shm_table_entry_t, entry) { if (strcmp(key, tpos->key) == 0) return tpos; } return NULL; } TOOLKIT_API int shm_table_create(shm_table_t **p_table) { int i; shm_table_t *table; shm_table_core *core; if (!p_table) return -1; table = (shm_table_t*)malloc(sizeof(shm_table_t)); memset(table, 0, sizeof(shm_table_t)); table->first = TRUE; core = shm_malloc(sizeof(shm_table_core)); memset(core, 0, sizeof(shm_table_core)); for (i = 0; i < HTABLE_SLOT_NUM; ++i) INIT_HLIST_HEAD(&core->hlist[i]); table->core = core; table->hMutex = create_mutex((int)core); if (!table->hMutex) { shm_table_destroy(table); return -1; } *p_table = table; return 0; } TOOLKIT_API int shm_table_open(void *core, shm_table_t **p_table) { shm_table_t *table; if (!p_table || !core) return -1; table = (shm_table_t*)malloc(sizeof(shm_table_t)); memset(table, 0, sizeof(shm_table_t)); table->first = FALSE; table->core = core; table->hMutex = create_mutex((int)core); if (!table->hMutex) { shm_table_destroy(table); return -1; } *p_table = table; return 0; } TOOLKIT_API void *shm_table_get_core_mem(shm_table_t *table) { return table->core; } TOOLKIT_API int shm_table_lock(shm_table_t *table, int timeout) { DWORD dwRet; dwRet = WaitForSingleObject(table->hMutex, (DWORD)timeout); return dwRet == WAIT_OBJECT_0 ? 0 : -1; } TOOLKIT_API int shm_table_unlock(shm_table_t *table) { return ReleaseMutex(table->hMutex) ? 0 : -1; } TOOLKIT_API int shm_table_destroy(shm_table_t *table) { if (table) { if (table->hMutex) CloseHandle(table->hMutex); if (table->first) { shm_free(table->core); } free(table); return 0; } return -1; } TOOLKIT_API int shm_table_set(shm_table_t *table, const char *key, const char *buf, int n) { int idx; shm_table_entry_t *e; shm_table_core *core; if (!table) return -1; if (n == -1 && buf) n = strlen(buf) + 1; core = table->core; idx = hash32_str(key, HASH32_STR_INIT) % HTABLE_SLOT_NUM; e = find_entry(&core->hlist[idx], key); if (e) { // update if (!buf) { // delete shm_free(e->key); shm_free(e->data); hlist_del(&e->entry); shm_free(e); } else { char *new_data = shm_malloc(n); if (!new_data) return -1; memcpy(new_data, buf, n); shm_free(e->data); e->data = new_data; e->len = n; } } else { // insert new if (!buf) return -1; e = (shm_table_entry_t*)shm_malloc(sizeof(shm_table_entry_t)); if (!e) return -1; e->key = shm_strdup(key); if (!e->key) { shm_free(e); return -1; } e->data = shm_malloc(n); if (!e->data) { shm_free(e->key); shm_free(e); return -1; } memcpy(e->data, buf, n); e->len = n; hlist_add_head(&e->entry, &core->hlist[idx]); } return 0; } TOOLKIT_API int shm_table_get(shm_table_t *table, const char *key, char *buf, int *n) { int idx; shm_table_entry_t *e; shm_table_core *core; if (!table) return -1; core = table->core; idx = hash32_str(key, HASH32_STR_INIT) % HTABLE_SLOT_NUM; e = find_entry(&core->hlist[idx], key); if (!e) return -1; if (buf) { if (n) { if (*n < e->len) { *n = e->len; return -1; } } memcpy(buf, e->data, e->len); } else { if (n) { *n = e->len; } else { return -1; } } return 0; } TOOLKIT_API int shm_table_set_int(shm_table_t *table, const char *key, int val) { return shm_table_set(table, key, (char*)&val, sizeof(int)); } TOOLKIT_API int shm_table_get_int(shm_table_t *table, const char *key, int* val) { if (!table || !val) return -1; return shm_table_get(table, key, (char*)val, NULL); } TOOLKIT_API int shm_table_incr_int(shm_table_t *table, const char *key, int *newvalue) { int idx; shm_table_entry_t *e; shm_table_core *core; if (!table) return -1; core = table->core; idx = hash32_str(key, HASH32_STR_INIT) % HTABLE_SLOT_NUM; e = find_entry(&core->hlist[idx], key); if (!e) return -1; if (e->len != sizeof(int)) return -1; *(int*)e->data = *(int*)e->data + 1; if (newvalue) *newvalue = *(int*)e->data; return 0; } TOOLKIT_API int shm_table_decr_int(shm_table_t *table, const char *key, int *newvalue) { int idx; shm_table_entry_t *e; shm_table_core *core; if (!table) return -1; core = table->core; idx = hash32_str(key, HASH32_STR_INIT) % HTABLE_SLOT_NUM; e = find_entry(&core->hlist[idx], key); if (!e) return -1; if (e->len != sizeof(int)) return -1; *(int*)e->data = *(int*)e->data - 1; if (newvalue) *newvalue = *(int*)e->data; return 0; }