33 static pthread_mutex_t
mutex = PTHREAD_MUTEX_INITIALIZER;
37 static GHashTable * logged;
39 static void str_log (
const char * str,
const char * op,
const char * file,
int line)
42 logged = g_hash_table_new_full (g_str_hash, g_str_equal, g_free,
NULL);
44 GList * list = g_hash_table_lookup (logged, str);
45 list = g_list_prepend (list, g_strdup_printf (
"%s by %s:%d", op, file, line));
46 g_hash_table_insert (logged, g_strdup (str), list);
49 static void str_log_dump (
const char * str)
54 for (GList * node = g_hash_table_lookup (logged, str); node; node = node->next)
55 printf (
" - %s\n", (
char *) node->data);
61 * ((
char *) str - 1) = 0;
62 free ((
char *) str - 5);
66 EXPORT
char * str_get_debug (
const char * str,
const char * file,
int line)
75 pthread_mutex_lock (&
mutex);
78 str_log (str,
"get", file, line);
84 if ((copy = g_hash_table_lookup (
table, str)))
86 void * mem = copy - 5;
87 (* (int32_t *) mem) ++;
91 void * mem = malloc (6 + strlen (str));
92 (* (int32_t *) mem) = 1;
94 copy = (
char *) mem + 5;
98 g_hash_table_insert (
table, copy, copy);
101 pthread_mutex_unlock (&
mutex);
106 EXPORT
char * str_ref_debug (
char * str,
const char * file,
int line)
114 pthread_mutex_lock (&
mutex);
118 str_log (str,
"ref", file, line);
121 void * mem = str - 5;
122 (* (int32_t *) mem) ++;
124 pthread_mutex_unlock (&
mutex);
129 EXPORT
void str_unref_debug (
char * str,
const char * file,
int line)
137 pthread_mutex_lock (&
mutex);
141 str_log (str,
"unref", file, line);
144 void * mem = str - 5;
145 if (! -- (* (int32_t *) mem))
146 g_hash_table_remove (
table, str);
148 pthread_mutex_unlock (&
mutex);
153 if (strlen (str) <= len)
157 memcpy (buf, str, len);
167 va_start (args, format);
168 int len = vsnprintf (
NULL, 0, format, args);
173 va_start (args, format);
174 vsnprintf (buf,
sizeof buf, format, args);
182 fprintf (stderr,
"String not in pool: %s\n", str);
189 static void str_leaked (
void * key,
void * str,
void * unused)
191 fprintf (stderr,
"String not freed: %s\n", (
char *) str);
203 g_hash_table_destroy (
table);
void strpool_shutdown(void)
static void str_destroy(void *str)
static GHashTable * table
char * str_printf(const char *format,...)
static pthread_mutex_t mutex
char * str_ref(char *str)
char * str_nget(const char *str, int len)
void str_unref(char *str)
void strpool_abort(char *str)
static void str_leaked(void *key, void *str, void *unused)
char * str_get(const char *str)