Commit 37330041 authored by Pekka Pessi's avatar Pekka Pessi
Browse files

su_home_new and su_home_unref

Added su_home_new() and su_home_unref().

Fixed su_home_mutex_lock() and su_home_mutex_unlock().

Slightly changed semantics of su_home_clone() versus su_home_threadsafe().

darcs-hash:20050908001135-65a35-9408f1630a3ec6b926461e82525cf7bf3fd67685.gz
parent 40e92f1a
...@@ -221,7 +221,7 @@ int header_size(http_header_t *h) ...@@ -221,7 +221,7 @@ int header_size(http_header_t *h)
/** Test header filtering and duplicating */ /** Test header filtering and duplicating */
static int tag_test(void) static int tag_test(void)
{ {
su_home_t *home = su_home_create(); su_home_t *home = su_home_new(sizeof *home);
http_request_t *request = http_request_t *request =
http_request_make(home, "GET /test/path HTTP/1.1"); http_request_make(home, "GET /test/path HTTP/1.1");
http_via_t *via = http_via_make(home, "1.1 http.example.com, 1.0 fred"); http_via_t *via = http_via_make(home, "1.1 http.example.com, 1.0 fred");
...@@ -268,7 +268,7 @@ static int tag_test(void) ...@@ -268,7 +268,7 @@ static int tag_test(void)
su_free(NULL, dup); su_free(NULL, dup);
tl_vfree(lst); tl_vfree(lst);
su_home_destroy(home); su_home_unref(home);
END(); END();
} }
...@@ -288,7 +288,7 @@ static int tag_test2(void) ...@@ -288,7 +288,7 @@ static int tag_test2(void)
su_home_t *home; su_home_t *home;
int xtra; int xtra;
home = su_home_create(); home = su_home_new(sizeof *home);
msg = read_message("HTTP/2.0 401 Unauthorized\r\n" msg = read_message("HTTP/2.0 401 Unauthorized\r\n"
"Content-Length: 0\r\n" "Content-Length: 0\r\n"
...@@ -392,7 +392,7 @@ static int tag_test2(void) ...@@ -392,7 +392,7 @@ static int tag_test2(void)
su_home_check(home); su_home_check(home);
su_home_destroy(home); su_home_unref(home);
#endif #endif
END(); END();
...@@ -523,7 +523,7 @@ static int http_header_handling_test(void) ...@@ -523,7 +523,7 @@ static int http_header_handling_test(void)
http_content_type_init(http_content_type); http_content_type_init(http_content_type);
http_content_length_init(http_content_length); http_content_length_init(http_content_length);
home = su_home_create(); home = su_home_new(sizeof *home);
{ {
int i; int i;
...@@ -815,7 +815,7 @@ static int http_header_handling_test(void) ...@@ -815,7 +815,7 @@ static int http_header_handling_test(void)
TEST(http_content_length_class->hc_params, TEST(http_content_length_class->hc_params,
offsetof(http_content_length_t, l_common)); offsetof(http_content_length_t, l_common));
su_home_destroy(home); su_home_unref(home);
END(); END();
} }
......
...@@ -751,7 +751,7 @@ static int test_warning(void) ...@@ -751,7 +751,7 @@ static int test_warning(void)
BEGIN(); BEGIN();
TEST_1(home = su_home_create()); TEST_1(home = su_home_new(sizeof *home));
TEST_1((w = msg_warning_make(home, TEST_1((w = msg_warning_make(home,
"399 host:5060 \"Ok\", " "399 host:5060 \"Ok\", "
...@@ -772,7 +772,7 @@ static int test_warning(void) ...@@ -772,7 +772,7 @@ static int test_warning(void)
TEST_S(buf, "399 [::1]:39999 \"foo\\\" bar\""); TEST_S(buf, "399 [::1]:39999 \"foo\\\" bar\"");
su_home_destroy(home), su_free(NULL, home); su_home_unref(home);
END(); END();
} }
......
...@@ -244,5 +244,8 @@ int table_test(int flags) ...@@ -244,5 +244,8 @@ int table_test(int flags)
TEST(count(c, h), 9); TEST(count(c, h), 9);
} }
TEST_VOID(su_home_unref(c->c_home));
END(); END();
} }
This diff is collapsed.
...@@ -50,16 +50,26 @@ typedef SU_HOME_T su_home_t; ...@@ -50,16 +50,26 @@ typedef SU_HOME_T su_home_t;
typedef struct su_block_s su_block_t; typedef struct su_block_s su_block_t;
/** Thread-locking function. @internal */ /** Thread-locking function. @internal */
typedef void (su_alock_f)(int what); typedef struct su_alock su_alock_t;
/** Memory home structure */ /** Memory home structure */
struct su_home_s { struct su_home_s {
int suh_size; int suh_size;
su_block_t *suh_blocks; su_block_t *suh_blocks;
su_alock_f *suh_lock; su_alock_t *suh_lock;
}; };
#define SU_HOME_INIT(obj) { sizeof (obj), 0 } #define SU_HOME_INIT(obj) { 0 }
SU_DLL void *su_home_new(int size)
__attribute__((__malloc__));
SU_DLL void *su_home_ref(su_home_t *);
SU_DLL void su_home_unref(su_home_t *);
SU_DLL void *su_home_clone(su_home_t *parent, int size)
__attribute__((__malloc__));
#define su_home_zap(h) su_home_unref((h))
SU_DLL su_home_t *su_home_create(void) SU_DLL su_home_t *su_home_create(void)
__attribute__((__malloc__)); __attribute__((__malloc__));
...@@ -70,15 +80,16 @@ SU_DLL void su_home_deinit(su_home_t *h); ...@@ -70,15 +80,16 @@ SU_DLL void su_home_deinit(su_home_t *h);
SU_DLL void su_home_preload(su_home_t *h, int n, int size); SU_DLL void su_home_preload(su_home_t *h, int n, int size);
SU_DLL void *su_home_clone(su_home_t *, int n) SU_DLL su_home_t *su_home_incref(su_home_t const *);
__attribute__((__malloc__));
SU_DLL void su_home_zap(su_home_t *); SU_DLL void su_home_decref(su_home_t *);
SU_DLL int su_home_move(su_home_t *dst, su_home_t *src); SU_DLL int su_home_move(su_home_t *dst, su_home_t *src);
SU_DLL int su_home_threadsafe(su_home_t *home); SU_DLL int su_home_threadsafe(su_home_t *home);
SU_DLL int su_home_has_parent(su_home_t const *home);
SU_DLL void su_home_check(su_home_t const *home); SU_DLL void su_home_check(su_home_t const *home);
SU_DLL int su_home_mutex_lock(su_home_t *home); SU_DLL int su_home_mutex_lock(su_home_t *home);
...@@ -110,7 +121,4 @@ SU_DLL char *su_vsprintf(su_home_t *home, char const *fmt, va_list ap) ...@@ -110,7 +121,4 @@ SU_DLL char *su_vsprintf(su_home_t *home, char const *fmt, va_list ap)
/* free an independent block */ /* free an independent block */
SU_DLL void su_free(su_home_t *h, void *); SU_DLL void su_free(su_home_t *h, void *);
/** Add a thread-locking function to the home. @internal */
SU_DLL int su_home_set_locker_(su_home_t *h, su_alock_f locker);
#endif /* ! defined(SU_ALLOC_H) */ #endif /* ! defined(SU_ALLOC_H) */
...@@ -46,6 +46,22 @@ char const su_alloc_lock_c_id[] = ...@@ -46,6 +46,22 @@ char const su_alloc_lock_c_id[] =
extern void (*su_home_locker)(void *mutex); extern void (*su_home_locker)(void *mutex);
extern void (*su_home_unlocker)(void *mutex); extern void (*su_home_unlocker)(void *mutex);
extern void (*su_home_mutex_locker)(void *mutex);
extern void (*su_home_mutex_unlocker)(void *mutex);
/** Mutex */
static void mutex_locker(void *_mutex)
{
pthread_mutex_t *mutex = _mutex;
pthread_mutex_lock(mutex + 1);
}
static void mutex_unlocker(void *_mutex)
{
pthread_mutex_t *mutex = _mutex;
pthread_mutex_unlock(mutex + 1);
}
/** Convert su_home_t object to a thread-safe one. /** Convert su_home_t object to a thread-safe one.
* *
* The function su_home_threadsafe() converts a memory home object * The function su_home_threadsafe() converts a memory home object
...@@ -58,22 +74,29 @@ extern void (*su_home_unlocker)(void *mutex); ...@@ -58,22 +74,29 @@ extern void (*su_home_unlocker)(void *mutex);
*/ */
int su_home_threadsafe(su_home_t *home) int su_home_threadsafe(su_home_t *home)
{ {
static int locker_set = 0;
pthread_mutex_t *mutex; pthread_mutex_t *mutex;
if (!locker_set) { if (home == NULL || home->suh_lock)
/* Avoid linking pthread library just for memory management... */ return 0;
assert(!su_home_has_parent(home));
if (su_home_has_parent(home))
return -1;
if (!su_home_unlocker) {
/* Avoid linking pthread library just for memory management */
su_home_mutex_locker = mutex_locker;
su_home_mutex_unlocker = mutex_unlocker;
su_home_locker = (void *)pthread_mutex_lock; su_home_locker = (void *)pthread_mutex_lock;
su_home_unlocker = (void *)pthread_mutex_unlock; su_home_unlocker = (void *)pthread_mutex_unlock;
locker_set = 1;
} }
if (home == NULL || home->suh_lock) mutex = su_alloc(home, 2 * sizeof (pthread_mutex_t));
return 0;
mutex = su_alloc(home, sizeof (pthread_mutex_t));
if (mutex) { if (mutex) {
/* Mutex for memory operations */
pthread_mutex_init(mutex, NULL); pthread_mutex_init(mutex, NULL);
/* Mutex used for explicit locking */
pthread_mutex_init(mutex + 1, NULL);
home->suh_lock = (void *)mutex; home->suh_lock = (void *)mutex;
return 0; return 0;
} }
......
...@@ -94,16 +94,18 @@ int test_alloc(void) ...@@ -94,16 +94,18 @@ int test_alloc(void)
BEGIN(); BEGIN();
TEST_1(h0 = su_home_clone(NULL, sizeof(*h0))); TEST_1(h0 = su_home_new(sizeof(*h0)));
TEST_1(h1 = su_home_clone(h0, sizeof(*h1)));
TEST_1(h2 = su_home_ref(h0));
su_home_unref(h0);
su_home_unref(h2);
TEST_1(h0 = su_home_new(sizeof(*h0)));
TEST_1(h1 = su_home_clone(h0, sizeof(*h1))); TEST_1(h1 = su_home_clone(h0, sizeof(*h1)));
TEST_1(h2 = su_home_clone(h1, sizeof(*h2))); TEST_1(h2 = su_home_clone(h1, sizeof(*h2)));
TEST_1(h3 = su_home_clone(h2, sizeof(*h3))); TEST_1(h3 = su_home_clone(h2, sizeof(*h3)));
TEST(su_home_threadsafe(h0), 0); TEST(su_home_threadsafe(h0), 0);
TEST(su_home_threadsafe(h1), 0);
TEST(su_home_threadsafe(h2), 0);
TEST(su_home_threadsafe(h3), 0);
TEST(su_home_threadsafe(home), 0);
for (i = 0; i < N; i++) { for (i = 0; i < N; i++) {
TEST_1(m0[i] = su_zalloc(h3, 20)); TEST_1(m0[i] = su_zalloc(h3, 20));
...@@ -136,6 +138,7 @@ int test_alloc(void) ...@@ -136,6 +138,7 @@ int test_alloc(void)
TEST(c = su_realloc(home, c, 0), NULL); TEST(c = su_realloc(home, c, 0), NULL);
su_home_check(home); su_home_check(home);
su_home_deinit(home);
su_home_check(h0); su_home_check(h0);
su_home_zap(h2); su_home_zap(h2);
...@@ -181,6 +184,7 @@ static int test_strlst(void) ...@@ -181,6 +184,7 @@ static int test_strlst(void)
TEST_1(!su_strlst_copy(home, NULL)); TEST_1(!su_strlst_copy(home, NULL));
TEST_VOID(su_strlst_destroy(NULL)); TEST_VOID(su_strlst_destroy(NULL));
TEST_VOID(su_strlst_destroy(l));
TEST_1(!su_strlst_dup_append(NULL, "aa")); TEST_1(!su_strlst_dup_append(NULL, "aa"));
TEST_1(!su_strlst_append(NULL, "bee")); TEST_1(!su_strlst_append(NULL, "bee"));
...@@ -196,6 +200,7 @@ static int test_strlst(void) ...@@ -196,6 +200,7 @@ static int test_strlst(void)
TEST_1(l = su_strlst_split(home, s, NULL)); TEST_1(l = su_strlst_split(home, s, NULL));
TEST_S(su_strlst_item(l, 0), "aaa"); TEST_S(su_strlst_item(l, 0), "aaa");
TEST_VOID(su_strlst_destroy(l)); TEST_VOID(su_strlst_destroy(l));
TEST_VOID(su_free(home, s)); TEST_VOID(su_free(home, s));
TEST_1(!su_strlst_dup_split(home, NULL, ".")); TEST_1(!su_strlst_dup_split(home, NULL, "."));
...@@ -207,6 +212,8 @@ static int test_strlst(void) ...@@ -207,6 +212,8 @@ static int test_strlst(void)
TEST(su_strlst_len(NULL), 0); TEST(su_strlst_len(NULL), 0);
TEST_1(!su_strlst_get_array(NULL)); TEST_1(!su_strlst_get_array(NULL));
TEST_VOID(su_strlst_free_array(NULL, NULL)); TEST_VOID(su_strlst_free_array(NULL, NULL));
TEST_1(l = su_strlst_create(home)); TEST_1(l = su_strlst_create(home));
TEST_VOID(su_strlst_free_array(l, NULL)); TEST_VOID(su_strlst_free_array(l, NULL));
TEST_S(su_strlst_dup_append(l, "oh"), "oh"); TEST_S(su_strlst_dup_append(l, "oh"), "oh");
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment