- better dbg code
[m6w6/ext-http] / http_persistent_handle_api.c
1 /*
2 +--------------------------------------------------------------------+
3 | PECL :: http |
4 +--------------------------------------------------------------------+
5 | Redistribution and use in source and binary forms, with or without |
6 | modification, are permitted provided that the conditions mentioned |
7 | in the accompanying LICENSE file are met. |
8 +--------------------------------------------------------------------+
9 | Copyright (c) 2004-2006, Michael Wallner <mike@php.net> |
10 +--------------------------------------------------------------------+
11 */
12
13 /* $Id$ */
14
15 #include "php_http.h"
16
17 #ifdef HTTP_HAVE_PERSISTENT_HANDLES
18
19 #include "php_http_persistent_handle_api.h"
20
21 static HashTable http_persistent_handles_hash;
22 #ifdef ZTS
23 # define LOCK() tsrm_mutex_lock(http_persistent_handles_lock)
24 # define UNLOCK() tsrm_mutex_unlock(http_persistent_handles_lock)
25 static MUTEX_T http_persistent_handles_lock;
26 #else
27 # define LOCK()
28 # define UNLOCK()
29 #endif
30
31 typedef struct _http_persistent_handles_hash_entry_t {
32 HashTable list;
33 http_persistent_handle_ctor ctor;
34 http_persistent_handle_dtor dtor;
35 } http_persistent_handles_hash_entry;
36
37 typedef struct _http_persistent_handles_list_entry_t {
38 void *handle;
39 } http_persistent_handles_list_entry;
40
41 static inline void http_persistent_handles_hash_dtor_ex(http_persistent_handles_hash_entry *hentry, void (*list_dtor)(HashTable*))
42 {
43 http_persistent_handles_list_entry *lentry;
44
45 for ( zend_hash_internal_pointer_reset(&hentry->list);
46 SUCCESS == zend_hash_get_current_data(&hentry->list, (void *) &lentry);
47 zend_hash_move_forward(&hentry->list)) {
48 hentry->dtor(lentry->handle);
49 }
50
51 if (list_dtor) {
52 list_dtor(&hentry->list);
53 }
54 }
55
56 static void http_persistent_handles_hash_dtor(void *h)
57 {
58 http_persistent_handles_hash_dtor_ex(h, zend_hash_destroy);
59 }
60
61 PHP_MINIT_FUNCTION(http_persistent_handle)
62 {
63 zend_hash_init(&http_persistent_handles_hash, 0, NULL, http_persistent_handles_hash_dtor, 1);
64 #ifdef ZTS
65 http_persistent_handles_lock = tsrm_mutex_alloc();
66 #endif
67 return SUCCESS;
68 }
69
70 PHP_MSHUTDOWN_FUNCTION(http_persistent_handle)
71 {
72 zend_hash_destroy(&http_persistent_handles_hash);
73 #ifdef ZTS
74 tsrm_mutex_free(http_persistent_handles_lock);
75 #endif
76 return SUCCESS;
77 }
78
79 PHP_HTTP_API STATUS _http_persistent_handle_provide_ex(const char *name_str, size_t name_len, http_persistent_handle_ctor ctor, http_persistent_handle_dtor dtor)
80 {
81 STATUS status = SUCCESS;
82 http_persistent_handles_hash_entry e;
83
84 zend_hash_init(&e.list, 0, NULL, NULL, 1);
85 e.ctor = ctor;
86 e.dtor = dtor;
87
88 LOCK();
89 if (SUCCESS != zend_hash_add(&http_persistent_handles_hash, (char *) name_str, name_len+1, (void *) &e, sizeof(http_persistent_handles_hash_entry), NULL)) {
90 zend_hash_destroy(&e.list);
91 status = FAILURE;
92 }
93 UNLOCK();
94
95 return status;
96 }
97
98 PHP_HTTP_API void _http_persistent_handle_cleanup_ex(const char *name_str, size_t name_len)
99 {
100 http_persistent_handles_hash_entry *hentry;
101
102 LOCK();
103 if (name_str && name_len) {
104 if (SUCCESS == zend_hash_find(&http_persistent_handles_hash, (char *) name_str, name_len+1, (void *) &hentry)) {
105 http_persistent_handles_hash_dtor_ex(hentry, zend_hash_clean);
106 }
107 } else {
108 for ( zend_hash_internal_pointer_reset(&http_persistent_handles_hash);
109 SUCCESS == zend_hash_get_current_data(&http_persistent_handles_hash, (void *) &hentry);
110 zend_hash_move_forward(&http_persistent_handles_hash)) {
111 http_persistent_handles_hash_dtor_ex(hentry, zend_hash_clean);
112 }
113 }
114 UNLOCK();
115 }
116
117 PHP_HTTP_API int _http_persistent_handle_statall_ex(char ***names, int **counts, int persistent)
118 {
119 int i, n;
120 char *key;
121 http_persistent_handles_hash_entry *hentry;
122
123 LOCK();
124 if ((n = zend_hash_num_elements(&http_persistent_handles_hash))) {
125 *names = safe_pemalloc(n, sizeof(char **), 0, persistent);
126 *counts = safe_pemalloc(n, sizeof(int), 0, persistent);
127
128 for ( i = 0, zend_hash_internal_pointer_reset(&http_persistent_handles_hash);
129 HASH_KEY_NON_EXISTANT != zend_hash_get_current_key(&http_persistent_handles_hash, &key, NULL, 0) &&
130 SUCCESS == zend_hash_get_current_data(&http_persistent_handles_hash, (void *) &hentry);
131 ++i, zend_hash_move_forward(&http_persistent_handles_hash)) {
132 (*names)[i] = pestrdup(key, persistent);
133 (*counts)[i] = zend_hash_num_elements(&hentry->list);
134 }
135 }
136 UNLOCK();
137
138 return n;
139 }
140
141 PHP_HTTP_API STATUS _http_persistent_handle_acquire_ex(const char *name_str, size_t name_len, void **handle)
142 {
143 STATUS status = FAILURE;
144 ulong index;
145 http_persistent_handles_hash_entry *hentry;
146 http_persistent_handles_list_entry *lentry;
147
148 LOCK();
149 if (SUCCESS == zend_hash_find(&http_persistent_handles_hash, (char *) name_str, name_len+1, (void *) &hentry)) {
150 zend_hash_internal_pointer_end(&hentry->list);
151 if ( HASH_KEY_NON_EXISTANT != zend_hash_get_current_key(&hentry->list, NULL, &index, 0) &&
152 SUCCESS == zend_hash_get_current_data(&hentry->list, (void *) &lentry)) {
153 *handle = lentry->handle;
154 zend_hash_index_del(&hentry->list, index);
155 status = SUCCESS;
156 } else if ((*handle = hentry->ctor())) {
157 status = SUCCESS;
158 }
159 }
160 UNLOCK();
161
162 return status;
163 }
164
165 PHP_HTTP_API STATUS _http_persistent_handle_release_ex(const char *name_str, size_t name_len, void **handle)
166 {
167 STATUS status = FAILURE;
168 http_persistent_handles_hash_entry *hentry;
169 http_persistent_handles_list_entry lentry;
170
171 LOCK();
172 if (SUCCESS == zend_hash_find(&http_persistent_handles_hash, (char *) name_str, name_len+1, (void *) &hentry)) {
173 lentry.handle = *handle;
174 if (SUCCESS == zend_hash_next_index_insert(&hentry->list, (void *) &lentry, sizeof(http_persistent_handles_list_entry), NULL)) {
175 status = SUCCESS;
176 }
177 }
178 UNLOCK();
179
180 return status;
181 }
182
183 #endif /* HTTP_HAVE_PERSISTENT_HANDLES */
184
185 /*
186 * Local variables:
187 * tab-width: 4
188 * c-basic-offset: 4
189 * End:
190 * vim600: noet sw=4 ts=4 fdm=marker
191 * vim<600: noet sw=4 ts=4
192 */
193