1 /*
2 +-----------------------------------------------------------------------------------+
3 | ZMQ extension for PHP |
4 | Copyright (c) 2010-2016, Mikko Koppanen <mkoppanen@php.net> |
5 | All rights reserved. |
6 +-----------------------------------------------------------------------------------+
7 | Redistribution and use in source and binary forms, with or without |
8 | modification, are permitted provided that the following conditions are met: |
9 | * Redistributions of source code must retain the above copyright |
10 | notice, this list of conditions and the following disclaimer. |
11 | * Redistributions in binary form must reproduce the above copyright |
12 | notice, this list of conditions and the following disclaimer in the |
13 | documentation and/or other materials provided with the distribution. |
14 | * Neither the name of the copyright holder nor the |
15 | names of its contributors may be used to endorse or promote products |
16 | derived from this software without specific prior written permission. |
17 +-----------------------------------------------------------------------------------+
18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND |
19 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
20 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
21 | DISCLAIMED. IN NO EVENT SHALL MIKKO KOPPANEN BE LIABLE FOR ANY |
22 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
23 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
24 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
25 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
27 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
28 +-----------------------------------------------------------------------------------+
29 */
30
31 #include "php_zmq.h"
32 #include "php_zmq_private.h"
33
34 #ifndef PHP_ZMQ_SHARED_CONTEXT_THREADS
35 # define PHP_ZMQ_SHARED_CONTEXT_THREADS 1
36 #endif
37
38 static
39 void *s_ctx;
40
41 static
42 int s_ctx_socket_count = 0;
43
44 static
45 int s_ctx_pid = 0;
46
47 #ifdef ZTS
48 static
49 MUTEX_T s_ctx_mutex;
50
51 static
s_shared_ctx_init()52 zend_bool s_shared_ctx_init()
53 {
54 if (!s_ctx) {
55 s_ctx_mutex = tsrm_mutex_alloc();
56 s_ctx_pid = getpid();
57 s_ctx = zmq_init(PHP_ZMQ_SHARED_CONTEXT_THREADS);
58 }
59 return (s_ctx != NULL);
60 }
61
62 static
s_shared_ctx_lock()63 zend_bool s_shared_ctx_lock()
64 {
65 if (!s_ctx_mutex) {
66 return 0;
67 }
68
69 return tsrm_mutex_lock(s_ctx_mutex) == 0;
70 }
71
72 static
s_shared_ctx_unlock()73 zend_bool s_shared_ctx_unlock()
74 {
75 if (!s_ctx_mutex) {
76 return 0;
77 }
78 return tsrm_mutex_unlock(s_ctx_mutex) == 0;
79 }
80
81 static
s_shared_ctx_destroy()82 void s_shared_ctx_destroy()
83 {
84 if (s_shared_ctx_lock()) {
85 if (s_ctx && s_ctx_pid == getpid()) {
86 MUTEX_T tmp_mutex = s_ctx_mutex;
87 s_ctx_mutex = NULL;
88
89 zmq_term(s_ctx);
90 s_ctx = NULL;
91 s_ctx_pid = -1;
92
93 tsrm_mutex_unlock(tmp_mutex);
94 tsrm_mutex_free(tmp_mutex);
95
96 s_ctx_mutex = NULL;
97 s_ctx_pid = -1;
98 return;
99 }
100 else {
101 s_shared_ctx_unlock();
102 }
103 }
104 }
105
106 #else
107
108 static
s_shared_ctx_init()109 zend_bool s_shared_ctx_init()
110 {
111 s_ctx = zmq_init(PHP_ZMQ_SHARED_CONTEXT_THREADS);
112 s_ctx_pid = getpid();
113 return (s_ctx != NULL);
114 }
115
116 static
s_shared_ctx_lock()117 zend_bool s_shared_ctx_lock()
118 {
119 return 1;
120 }
121 static
s_shared_ctx_unlock()122 zend_bool s_shared_ctx_unlock()
123 {
124 return 1;
125 }
126
127 static
s_shared_ctx_destroy()128 void s_shared_ctx_destroy()
129 {
130 if (s_ctx && s_ctx_pid == getpid()) {
131 zmq_term(s_ctx);
132
133 s_ctx = NULL;
134 s_ctx_pid = -1;
135 }
136 }
137 #endif
138
php_zmq_shared_ctx_init()139 zend_bool php_zmq_shared_ctx_init()
140 {
141 return
142 s_shared_ctx_init();
143 }
144
php_zmq_shared_ctx_assign_to(php_zmq_context * context)145 void php_zmq_shared_ctx_assign_to(php_zmq_context *context)
146 {
147 if (s_shared_ctx_lock()) {
148 context->z_ctx = s_ctx;
149 s_shared_ctx_unlock();
150 }
151 }
152
php_zmq_shared_ctx_destroy()153 void php_zmq_shared_ctx_destroy()
154 {
155 if (php_zmq_shared_ctx_socket_count() > 0) {
156 php_error_docref(NULL, E_WARNING, "php_zmq_shared_ctx_socket_count() > 0, please report a bug");
157 }
158 s_shared_ctx_destroy();
159 }
160
php_zmq_shared_ctx_socket_count()161 int php_zmq_shared_ctx_socket_count()
162 {
163 int value = 0;
164
165 if (s_shared_ctx_lock()) {
166 value = s_ctx_socket_count;
167 s_shared_ctx_unlock();
168 }
169 return value;
170 }
171
php_zmq_shared_ctx_socket_count_incr()172 void php_zmq_shared_ctx_socket_count_incr()
173 {
174 if (s_shared_ctx_lock()) {
175 s_ctx_socket_count++;
176 s_shared_ctx_unlock();
177 }
178 }
179
php_zmq_shared_ctx_socket_count_decr()180 void php_zmq_shared_ctx_socket_count_decr()
181 {
182 if (s_shared_ctx_lock()) {
183 s_ctx_socket_count--;
184 s_shared_ctx_unlock();
185 }
186 }
187
188
189
190