more use bits
This commit is contained in:
47
base/array.c
47
base/array.c
@@ -181,6 +181,51 @@ heim_object_t
|
|||||||
heim_array_copy_value(heim_array_t array, size_t idx)
|
heim_array_copy_value(heim_array_t array, size_t idx)
|
||||||
{
|
{
|
||||||
if (idx >= array->len)
|
if (idx >= array->len)
|
||||||
HEIM_BASE_ABORT("index too large");
|
heim_abort("index too large");
|
||||||
return heim_retain(array->val[idx]);
|
return heim_retain(array->val[idx]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete value at idx
|
||||||
|
*
|
||||||
|
* @param array the array to modify
|
||||||
|
* @param idx the key to delete
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
heim_array_delete_value(heim_array_t array, size_t idx)
|
||||||
|
{
|
||||||
|
heim_object_t obj;
|
||||||
|
if (idx >= array->len)
|
||||||
|
heim_abort("index too large");
|
||||||
|
obj = array->val[idx];
|
||||||
|
|
||||||
|
array->len--;
|
||||||
|
|
||||||
|
if (idx < array->len)
|
||||||
|
memmove(&array->val[idx], &array->val[idx + 1],
|
||||||
|
(array->len - idx) * sizeof(array->val[0]));
|
||||||
|
|
||||||
|
heim_release(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get value at idx
|
||||||
|
*
|
||||||
|
* @param array the array to modify
|
||||||
|
* @param idx the key to delete
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
heim_array_filter(heim_array_t array, bool (^block)(heim_object_t))
|
||||||
|
{
|
||||||
|
size_t n = 0;
|
||||||
|
|
||||||
|
while (n < array->len) {
|
||||||
|
if (block(array->val[n])) {
|
||||||
|
heim_array_delete_value(array, n);
|
||||||
|
} else {
|
||||||
|
n++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -40,8 +40,9 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "heim_threads.h"
|
|
||||||
|
|
||||||
|
#include "heimqueue.h"
|
||||||
|
#include "heim_threads.h"
|
||||||
#include "heimbase.h"
|
#include "heimbase.h"
|
||||||
#include "heimbasepriv.h"
|
#include "heimbasepriv.h"
|
||||||
|
|
||||||
@@ -49,8 +50,6 @@
|
|||||||
#include <dispatch/dispatch.h>
|
#include <dispatch/dispatch.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define HEIM_BASE_ABORT(x) abort()
|
|
||||||
|
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
#define heim_base_atomic_inc(x) __sync_add_and_fetch((x), 1)
|
#define heim_base_atomic_inc(x) __sync_add_and_fetch((x), 1)
|
||||||
#define heim_base_atomic_dec(x) __sync_sub_and_fetch((x), 1)
|
#define heim_base_atomic_dec(x) __sync_sub_and_fetch((x), 1)
|
||||||
@@ -80,3 +79,12 @@
|
|||||||
((heim_object_t)((((uintptr_t)(x)) << 5) | ((tid) << 2) | 0x1))
|
((heim_object_t)((((uintptr_t)(x)) << 5) | ((tid) << 2) | 0x1))
|
||||||
#define heim_base_tagged_object_tid(x) ((((uintptr_t)(x)) & 0x1f) >> 2)
|
#define heim_base_tagged_object_tid(x) ((((uintptr_t)(x)) & 0x1f) >> 2)
|
||||||
#define heim_base_tagged_object_value(x) (((uintptr_t)(x)) >> 5)
|
#define heim_base_tagged_object_value(x) (((uintptr_t)(x)) >> 5)
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#undef HEIMDAL_NORETURN_ATTRIBUTE
|
||||||
|
#define HEIMDAL_NORETURN_ATTRIBUTE
|
||||||
|
#undef HEIMDAL_PRINTF_ATTRIBUTE
|
||||||
|
#define HEIMDAL_PRINTF_ATTRIBUTE(x)
|
||||||
|
253
base/heimbase.c
253
base/heimbase.c
@@ -34,27 +34,43 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "baselocl.h"
|
#include "baselocl.h"
|
||||||
|
#include <syslog.h>
|
||||||
|
|
||||||
static heim_base_atomic_type tidglobal = HEIM_TID_USER;
|
static heim_base_atomic_type tidglobal = HEIM_TID_USER;
|
||||||
|
|
||||||
struct heim_base {
|
struct heim_base {
|
||||||
heim_type_t isa;
|
heim_type_t isa;
|
||||||
heim_base_atomic_type ref_cnt;
|
heim_base_atomic_type ref_cnt;
|
||||||
uintptr_t isaextra[3];
|
HEIM_TAILQ_ENTRY(heim_base) autorel;
|
||||||
|
heim_auto_release_t autorelpool;
|
||||||
|
uintptr_t isaextra[3];
|
||||||
};
|
};
|
||||||
|
|
||||||
/* specialized version of base */
|
/* specialized version of base */
|
||||||
struct heim_base_mem {
|
struct heim_base_mem {
|
||||||
heim_type_t isa;
|
heim_type_t isa;
|
||||||
heim_base_atomic_type ref_cnt;
|
heim_base_atomic_type ref_cnt;
|
||||||
|
HEIM_TAILQ_ENTRY(heim_base) autorel;
|
||||||
|
heim_auto_release_t autorelpool;
|
||||||
const char *name;
|
const char *name;
|
||||||
void (*dealloc)(void *);
|
void (*dealloc)(void *);
|
||||||
uintptr_t isaextra[1];
|
uintptr_t isaextra[1];
|
||||||
};
|
};
|
||||||
|
|
||||||
#define PTR2BASE(ptr) (((struct heim_base *)ptr) - 1)
|
#define PTR2BASE(ptr) (((struct heim_base *)ptr) - 1)
|
||||||
#define BASE2PTR(ptr) ((void *)(((struct heim_base *)ptr) + 1))
|
#define BASE2PTR(ptr) ((void *)(((struct heim_base *)ptr) + 1))
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Auto release structure
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct heim_auto_release {
|
||||||
|
HEIM_TAILQ_HEAD(, heim_base) pool;
|
||||||
|
HEIMDAL_MUTEX pool_mutex;
|
||||||
|
struct heim_auto_release *parent;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retain object
|
* Retain object
|
||||||
*
|
*
|
||||||
@@ -75,7 +91,7 @@ heim_retain(void *ptr)
|
|||||||
return ptr;
|
return ptr;
|
||||||
|
|
||||||
if ((heim_base_atomic_inc(&p->ref_cnt) - 1) == 0)
|
if ((heim_base_atomic_inc(&p->ref_cnt) - 1) == 0)
|
||||||
HEIM_BASE_ABORT("resurection");
|
heim_abort("resurection");
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -103,11 +119,19 @@ heim_release(void *ptr)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
if (old == 1) {
|
if (old == 1) {
|
||||||
|
heim_auto_release_t ar = p->autorelpool;
|
||||||
|
/* remove from autorel pool list */
|
||||||
|
if (ar) {
|
||||||
|
p->autorelpool = NULL;
|
||||||
|
HEIMDAL_MUTEX_lock(&ar->pool_mutex);
|
||||||
|
HEIM_TAILQ_REMOVE(&ar->pool, p, autorel);
|
||||||
|
HEIMDAL_MUTEX_unlock(&ar->pool_mutex);
|
||||||
|
}
|
||||||
if (p->isa->dealloc)
|
if (p->isa->dealloc)
|
||||||
p->isa->dealloc(ptr);
|
p->isa->dealloc(ptr);
|
||||||
free(p);
|
free(p);
|
||||||
} else
|
} else
|
||||||
HEIM_BASE_ABORT("over release");
|
heim_abort("over release");
|
||||||
}
|
}
|
||||||
|
|
||||||
static heim_type_t tagged_isa[9] = {
|
static heim_type_t tagged_isa[9] = {
|
||||||
@@ -133,7 +157,7 @@ _heim_get_isa(heim_object_t ptr)
|
|||||||
return tagged_isa[heim_base_tagged_object_tid(ptr)];
|
return tagged_isa[heim_base_tagged_object_tid(ptr)];
|
||||||
if (heim_base_is_tagged_string(ptr))
|
if (heim_base_is_tagged_string(ptr))
|
||||||
return &_heim_string_object;
|
return &_heim_string_object;
|
||||||
abort();
|
heim_abort("not a supported tagged type");
|
||||||
}
|
}
|
||||||
p = PTR2BASE(ptr);
|
p = PTR2BASE(ptr);
|
||||||
return p->isa;
|
return p->isa;
|
||||||
@@ -186,7 +210,7 @@ heim_cmp(heim_object_t a, heim_object_t b)
|
|||||||
{
|
{
|
||||||
heim_tid_t ta, tb;
|
heim_tid_t ta, tb;
|
||||||
heim_type_t isa;
|
heim_type_t isa;
|
||||||
|
|
||||||
ta = heim_get_tid(a);
|
ta = heim_get_tid(a);
|
||||||
tb = heim_get_tid(b);
|
tb = heim_get_tid(b);
|
||||||
|
|
||||||
@@ -248,8 +272,6 @@ _heim_create_type(const char *name,
|
|||||||
{
|
{
|
||||||
heim_type_t type;
|
heim_type_t type;
|
||||||
|
|
||||||
/* XXX posix_memalign */
|
|
||||||
|
|
||||||
type = calloc(1, sizeof(*type));
|
type = calloc(1, sizeof(*type));
|
||||||
if (type == NULL)
|
if (type == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -268,6 +290,7 @@ _heim_create_type(const char *name,
|
|||||||
heim_object_t
|
heim_object_t
|
||||||
_heim_alloc_object(heim_type_t type, size_t size)
|
_heim_alloc_object(heim_type_t type, size_t size)
|
||||||
{
|
{
|
||||||
|
/* XXX should use posix_memalign */
|
||||||
struct heim_base *p = calloc(1, size + sizeof(*p));
|
struct heim_base *p = calloc(1, size + sizeof(*p));
|
||||||
if (p == NULL)
|
if (p == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -312,7 +335,6 @@ heim_base_once_f(heim_base_once_t *once, void *ctx, void (*func)(void *))
|
|||||||
HEIMDAL_MUTEX_unlock(&mutex);
|
HEIMDAL_MUTEX_unlock(&mutex);
|
||||||
while (1) {
|
while (1) {
|
||||||
struct timeval tv = { 0, 1000 };
|
struct timeval tv = { 0, 1000 };
|
||||||
select(0, NULL, NULL, NULL, &tv);
|
|
||||||
HEIMDAL_MUTEX_lock(&mutex);
|
HEIMDAL_MUTEX_lock(&mutex);
|
||||||
if (*once == 2)
|
if (*once == 2)
|
||||||
break;
|
break;
|
||||||
@@ -322,3 +344,216 @@ heim_base_once_f(heim_base_once_t *once, void *ctx, void (*func)(void *))
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Abort and log the failure (using syslog)
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
heim_abort(const char *fmt, ...)
|
||||||
|
{
|
||||||
|
va_list ap;
|
||||||
|
va_start(ap, fmt);
|
||||||
|
heim_abortv(fmt, ap);
|
||||||
|
va_end(ap);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Abort and log the failure (using syslog)
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
heim_abortv(const char *fmt, va_list ap)
|
||||||
|
{
|
||||||
|
char *str = NULL;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = vasprintf(&str, fmt, ap);
|
||||||
|
if (ret > 0 && str) {
|
||||||
|
syslog(LOG_ERR, "heim_abort: %s", str);
|
||||||
|
}
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
static int ar_created = 0;
|
||||||
|
static HEIMDAL_thread_key ar_key;
|
||||||
|
|
||||||
|
struct ar_tls {
|
||||||
|
struct heim_auto_release *head;
|
||||||
|
struct heim_auto_release *current;
|
||||||
|
HEIMDAL_MUTEX tls_mutex;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
ar_tls_delete(void *ptr)
|
||||||
|
{
|
||||||
|
struct ar_tls *tls = ptr;
|
||||||
|
if (tls->head)
|
||||||
|
heim_release(tls->head);
|
||||||
|
free(tls);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
init_ar_tls(void *ptr)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
HEIMDAL_key_create(&ar_key, ar_tls_delete, ret);
|
||||||
|
if (ret == 0)
|
||||||
|
ar_created = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct ar_tls *
|
||||||
|
autorel_tls(void)
|
||||||
|
{
|
||||||
|
static heim_base_once_t once = HEIM_BASE_ONCE_INIT;
|
||||||
|
struct ar_tls *arp;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
heim_base_once_f(&once, NULL, init_ar_tls);
|
||||||
|
if (!ar_created)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
arp = HEIMDAL_getspecific(ar_key);
|
||||||
|
if (arp == NULL) {
|
||||||
|
|
||||||
|
arp = calloc(1, sizeof(*arp));
|
||||||
|
if (arp == NULL)
|
||||||
|
return NULL;
|
||||||
|
HEIMDAL_setspecific(ar_key, arp, ret);
|
||||||
|
if (ret) {
|
||||||
|
free(arp);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return arp;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
autorel_dealloc(void *ptr)
|
||||||
|
{
|
||||||
|
heim_auto_release_t ar = ptr;
|
||||||
|
struct ar_tls *tls;
|
||||||
|
|
||||||
|
tls = autorel_tls();
|
||||||
|
if (tls == NULL)
|
||||||
|
heim_abort("autorelease pool released on thread w/o autorelease inited");
|
||||||
|
|
||||||
|
heim_auto_release_drain(ar);
|
||||||
|
|
||||||
|
if (!HEIM_TAILQ_EMPTY(&ar->pool))
|
||||||
|
heim_abort("pool not empty after draining");
|
||||||
|
|
||||||
|
HEIMDAL_MUTEX_lock(&tls->tls_mutex);
|
||||||
|
if (tls->current != ptr)
|
||||||
|
heim_abort("autorelease not releaseing top pool");
|
||||||
|
|
||||||
|
if (tls->current != tls->head)
|
||||||
|
tls->current = ar->parent;
|
||||||
|
HEIMDAL_MUTEX_unlock(&tls->tls_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
autorel_cmp(void *a, void *b)
|
||||||
|
{
|
||||||
|
return (a == b);
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned long
|
||||||
|
autorel_hash(void *ptr)
|
||||||
|
{
|
||||||
|
return (unsigned long)ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static struct heim_type_data _heim_autorel_object = {
|
||||||
|
HEIM_TID_AUTORELEASE,
|
||||||
|
"autorelease-pool",
|
||||||
|
NULL,
|
||||||
|
autorel_dealloc,
|
||||||
|
NULL,
|
||||||
|
autorel_cmp,
|
||||||
|
autorel_hash
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
heim_auto_release_t
|
||||||
|
heim_auto_release_create(void)
|
||||||
|
{
|
||||||
|
struct ar_tls *tls = autorel_tls();
|
||||||
|
heim_auto_release_t ar;
|
||||||
|
|
||||||
|
if (tls == NULL)
|
||||||
|
heim_abort("Failed to create/get autorelease head");
|
||||||
|
|
||||||
|
ar = _heim_alloc_object(&_heim_autorel_object, sizeof(struct heim_auto_release));
|
||||||
|
if (ar) {
|
||||||
|
HEIMDAL_MUTEX_lock(&tls->tls_mutex);
|
||||||
|
if (tls->head == NULL)
|
||||||
|
tls->head = ar;
|
||||||
|
ar->parent = tls->current;
|
||||||
|
tls->current = ar;
|
||||||
|
HEIMDAL_MUTEX_unlock(&tls->tls_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ar;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mark the current object as a
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
heim_auto_release(heim_object_t ptr)
|
||||||
|
{
|
||||||
|
struct heim_base *p = PTR2BASE(ptr);
|
||||||
|
struct ar_tls *tls = autorel_tls();
|
||||||
|
heim_auto_release_t ar;
|
||||||
|
|
||||||
|
if (ptr == NULL || heim_base_is_tagged(ptr))
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* drop from old pool */
|
||||||
|
if ((ar = p->autorelpool) != NULL) {
|
||||||
|
HEIMDAL_MUTEX_lock(&ar->pool_mutex);
|
||||||
|
HEIM_TAILQ_REMOVE(&ar->pool, p, autorel);
|
||||||
|
p->autorelpool = NULL;
|
||||||
|
HEIMDAL_MUTEX_unlock(&ar->pool_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tls == NULL || (ar = tls->current) == NULL)
|
||||||
|
heim_abort("no auto relase pool in place, would leak");
|
||||||
|
|
||||||
|
HEIMDAL_MUTEX_lock(&ar->pool_mutex);
|
||||||
|
HEIM_TAILQ_INSERT_HEAD(&ar->pool, p, autorel);
|
||||||
|
p->autorelpool = ar;
|
||||||
|
HEIMDAL_MUTEX_unlock(&ar->pool_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
heim_auto_release_drain(heim_auto_release_t autorel)
|
||||||
|
{
|
||||||
|
heim_object_t obj;
|
||||||
|
|
||||||
|
/* release all elements on the tail queue */
|
||||||
|
|
||||||
|
HEIMDAL_MUTEX_lock(&autorel->pool_mutex);
|
||||||
|
while(!HEIM_TAILQ_EMPTY(&autorel->pool)) {
|
||||||
|
obj = HEIM_TAILQ_FIRST(&autorel->pool);
|
||||||
|
HEIMDAL_MUTEX_unlock(&autorel->pool_mutex);
|
||||||
|
heim_release(BASE2PTR(obj));
|
||||||
|
HEIMDAL_MUTEX_lock(&autorel->pool_mutex);
|
||||||
|
}
|
||||||
|
HEIMDAL_MUTEX_unlock(&autorel->pool_mutex);
|
||||||
|
}
|
||||||
|
@@ -37,6 +37,9 @@
|
|||||||
#define HEIM_BASE_H 1
|
#define HEIM_BASE_H 1
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
#include <krb5-types.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
typedef void * heim_object_t;
|
typedef void * heim_object_t;
|
||||||
typedef unsigned int heim_tid_t;
|
typedef unsigned int heim_tid_t;
|
||||||
@@ -61,6 +64,19 @@ heim_get_hash(heim_object_t ptr);
|
|||||||
void
|
void
|
||||||
heim_base_once_f(heim_base_once_t *, void *, void (*)(void *));
|
heim_base_once_f(heim_base_once_t *, void *, void (*)(void *));
|
||||||
|
|
||||||
|
void
|
||||||
|
heim_abort(const char *fmt, ...)
|
||||||
|
HEIMDAL_NORETURN_ATTRIBUTE
|
||||||
|
HEIMDAL_PRINTF_ATTRIBUTE((printf, 1, 2));
|
||||||
|
|
||||||
|
void
|
||||||
|
heim_abortv(const char *fmt, va_list ap)
|
||||||
|
HEIMDAL_NORETURN_ATTRIBUTE
|
||||||
|
HEIMDAL_PRINTF_ATTRIBUTE((printf, 1, 0));
|
||||||
|
|
||||||
|
#define heim_assert(e,t) \
|
||||||
|
(__builtin_expect(!(e), 0) ? heim_abort(t ":" #e) : (void)0)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@@ -93,6 +109,10 @@ void heim_array_iterate(heim_array_t, void (^)(heim_object_t));
|
|||||||
size_t heim_array_get_length(heim_array_t);
|
size_t heim_array_get_length(heim_array_t);
|
||||||
heim_object_t
|
heim_object_t
|
||||||
heim_array_copy_value(heim_array_t, size_t);
|
heim_array_copy_value(heim_array_t, size_t);
|
||||||
|
void heim_array_delete_value(heim_array_t, size_t);
|
||||||
|
#ifdef __BLOCKS__
|
||||||
|
void heim_array_filter(heim_array_t, bool (^)(heim_object_t));
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Dict
|
* Dict
|
||||||
@@ -136,4 +156,14 @@ heim_number_t heim_number_create(int);
|
|||||||
heim_tid_t heim_number_get_type_id(void);
|
heim_tid_t heim_number_get_type_id(void);
|
||||||
int heim_number_get_int(heim_number_t);
|
int heim_number_get_int(heim_number_t);
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef struct heim_auto_release * heim_auto_release_t;
|
||||||
|
|
||||||
|
heim_auto_release_t heim_auto_release_create(void);
|
||||||
|
void heim_auto_release_drain(heim_auto_release_t);
|
||||||
|
void heim_auto_release(heim_object_t);
|
||||||
|
|
||||||
#endif /* HEIM_BASE_H */
|
#endif /* HEIM_BASE_H */
|
||||||
|
@@ -54,6 +54,7 @@ enum {
|
|||||||
HEIM_TID_ARRAY = 129,
|
HEIM_TID_ARRAY = 129,
|
||||||
HEIM_TID_DICT = 130,
|
HEIM_TID_DICT = 130,
|
||||||
HEIM_TID_STRING = 131,
|
HEIM_TID_STRING = 131,
|
||||||
|
HEIM_TID_AUTORELEASE = 132,
|
||||||
HEIM_TID_USER = 255
|
HEIM_TID_USER = 255
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@@ -100,7 +100,13 @@ heim_string_create(const char *string)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a string object from a strings allocated in the text segment
|
* Create a string object from a strings allocated in the text segment.
|
||||||
|
*
|
||||||
|
* Note that static string object wont be auto released with
|
||||||
|
* heim_auto_release(), the allocation policy of the string must
|
||||||
|
* be manged separately from the returned object. This make this
|
||||||
|
* function not very useful for strings in allocated from heap or
|
||||||
|
* stack. In that case you should use heim_string_create().
|
||||||
*
|
*
|
||||||
* @param string the string to create, must be an utf8 string
|
* @param string the string to create, must be an utf8 string
|
||||||
*
|
*
|
||||||
@@ -126,7 +132,7 @@ heim_string_get_type_id(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the string value of the content
|
* Get the string value of the content.
|
||||||
*
|
*
|
||||||
* @param string the string object to get the value from
|
* @param string the string object to get the value from
|
||||||
*
|
*
|
||||||
|
@@ -91,13 +91,43 @@ test_dict(void)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
test_auto_release(void)
|
||||||
|
{
|
||||||
|
heim_auto_release_t ar1, ar2;
|
||||||
|
heim_number_t n1;
|
||||||
|
heim_string_t s1;
|
||||||
|
|
||||||
|
ar1 = heim_auto_release_create();
|
||||||
|
|
||||||
|
s1 = heim_string_create("hejsan");
|
||||||
|
heim_auto_release(s1);
|
||||||
|
|
||||||
|
s1 = heim_string_create_with_static("hejsan");
|
||||||
|
heim_auto_release(s1);
|
||||||
|
|
||||||
|
n1 = heim_number_create(1);
|
||||||
|
heim_auto_release(n1);
|
||||||
|
|
||||||
|
ar2 = heim_auto_release_create();
|
||||||
|
|
||||||
|
n1 = heim_number_create(1);
|
||||||
|
heim_auto_release(n1);
|
||||||
|
|
||||||
|
heim_release(ar2);
|
||||||
|
heim_release(ar1);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
main(int argc, char **argv)
|
main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
int res = 0;
|
int res = 0;
|
||||||
|
|
||||||
res += test_memory();
|
res |= test_memory();
|
||||||
res += test_dict();
|
res |= test_dict();
|
||||||
|
res |= test_auto_release();
|
||||||
|
|
||||||
return 0;
|
return res;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user