Skip to content

Commit f200f73

Browse files
author
Sander Roobol
committed
Made bcmath extension thread safe.
@made bcmath extension thread safe. (Sander)
1 parent 64a75d6 commit f200f73

14 files changed

Lines changed: 185 additions & 201 deletions

File tree

ext/bcmath/bcmath.c

Lines changed: 58 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@
3030
#include "php_bcmath.h"
3131
#include "libbcmath/src/bcmath.h"
3232

33+
ZEND_DECLARE_MODULE_GLOBALS(bcmath);
34+
3335
function_entry bcmath_functions[] = {
3436
PHP_FE(bcadd, NULL)
3537
PHP_FE(bcsub, NULL)
@@ -47,7 +49,11 @@ zend_module_entry bcmath_module_entry = {
4749
STANDARD_MODULE_HEADER,
4850
"bcmath",
4951
bcmath_functions,
52+
#if ZTS
53+
PHP_MODULE_STARTUP_N(bcmath),
54+
#else
5055
NULL,
56+
#endif
5157
NULL,
5258
PHP_RINIT(bcmath),
5359
PHP_RSHUTDOWN(bcmath),
@@ -64,32 +70,22 @@ ZEND_GET_MODULE(bcmath)
6470
static long bc_precision;
6571
#endif
6672

67-
/* Storage used for special numbers. */
68-
extern bc_num _zero_;
69-
extern bc_num _one_;
70-
extern bc_num _two_;
71-
72-
73-
/* Make a copy of a number! Just increments the reference count! */
74-
bc_num copy_num (bc_num num)
73+
#if ZTS
74+
PHP_MODULE_STARTUP_D(bcmath)
7575
{
76-
num->n_refs++;
77-
return num;
78-
}
76+
zend_bcmath_globals *bcmath_globals;
7977

80-
81-
/* Initialize a number NUM by making it a copy of zero. */
82-
void init_num (bc_num *num)
83-
{
84-
*num = copy_num (_zero_);
78+
ts_allocate_id(&bcmath_globals_id, sizeof(zend_bcmath_globals), NULL, NULL);
79+
bcmath_globals = ts_resource(bcmath_globals_id);
80+
return SUCCESS;
8581
}
86-
82+
#endif
8783

8884
PHP_RSHUTDOWN_FUNCTION(bcmath)
8985
{
90-
bc_free_num(&_zero_);
91-
bc_free_num(&_one_);
92-
bc_free_num(&_two_);
86+
bc_free_num(&BCG(_zero_));
87+
bc_free_num(&BCG(_one_));
88+
bc_free_num(&BCG(_two_));
9389

9490
return SUCCESS;
9591
}
@@ -101,7 +97,7 @@ PHP_RINIT_FUNCTION(bcmath)
10197
bc_precision=0;
10298
}
10399

104-
bc_init_numbers();
100+
bc_init_numbers(TSRMLS_C);
105101

106102
return SUCCESS;
107103
}
@@ -141,11 +137,11 @@ PHP_FUNCTION(bcadd)
141137
}
142138
convert_to_string_ex(left);
143139
convert_to_string_ex(right);
144-
bc_init_num(&first);
145-
bc_init_num(&second);
146-
bc_init_num(&result);
147-
bc_str2num(&first, Z_STRVAL_PP(left), scale);
148-
bc_str2num(&second, Z_STRVAL_PP(right), scale);
140+
bc_init_num(&first TSRMLS_CC);
141+
bc_init_num(&second TSRMLS_CC);
142+
bc_init_num(&result TSRMLS_CC);
143+
bc_str2num(&first, Z_STRVAL_PP(left), scale TSRMLS_CC);
144+
bc_str2num(&second, Z_STRVAL_PP(right), scale TSRMLS_CC);
149145
bc_add (first, second, &result, scale);
150146
Z_STRVAL_P(return_value) = bc_num2str(result);
151147
Z_STRLEN_P(return_value) = strlen(Z_STRVAL_P(return_value));
@@ -184,11 +180,11 @@ PHP_FUNCTION(bcsub)
184180
}
185181
convert_to_string_ex(left);
186182
convert_to_string_ex(right);
187-
bc_init_num(&first);
188-
bc_init_num(&second);
189-
bc_init_num(&result);
190-
bc_str2num(&first, Z_STRVAL_PP(left), scale);
191-
bc_str2num(&second, Z_STRVAL_PP(right), scale);
183+
bc_init_num(&first TSRMLS_CC);
184+
bc_init_num(&second TSRMLS_CC);
185+
bc_init_num(&result TSRMLS_CC);
186+
bc_str2num(&first, Z_STRVAL_PP(left), scale TSRMLS_CC);
187+
bc_str2num(&second, Z_STRVAL_PP(right), scale TSRMLS_CC);
192188
bc_sub (first, second, &result, scale);
193189
Z_STRVAL_P(return_value) = bc_num2str(result);
194190
Z_STRLEN_P(return_value) = strlen(Z_STRVAL_P(return_value));
@@ -227,12 +223,12 @@ PHP_FUNCTION(bcmul)
227223
}
228224
convert_to_string_ex(left);
229225
convert_to_string_ex(right);
230-
bc_init_num(&first);
231-
bc_init_num(&second);
232-
bc_init_num(&result);
233-
bc_str2num(&first, Z_STRVAL_PP(left), scale);
234-
bc_str2num(&second, Z_STRVAL_PP(right), scale);
235-
bc_multiply (first, second, &result, scale);
226+
bc_init_num(&first TSRMLS_CC);
227+
bc_init_num(&second TSRMLS_CC);
228+
bc_init_num(&result TSRMLS_CC);
229+
bc_str2num(&first, Z_STRVAL_PP(left), scale TSRMLS_CC);
230+
bc_str2num(&second, Z_STRVAL_PP(right), scale TSRMLS_CC);
231+
bc_multiply (first, second, &result, scale TSRMLS_CC);
236232
Z_STRVAL_P(return_value) = bc_num2str(result);
237233
Z_STRLEN_P(return_value) = strlen(Z_STRVAL_P(return_value));
238234
Z_TYPE_P(return_value) = IS_STRING;
@@ -270,12 +266,12 @@ PHP_FUNCTION(bcdiv)
270266
}
271267
convert_to_string_ex(left);
272268
convert_to_string_ex(right);
273-
bc_init_num(&first);
274-
bc_init_num(&second);
275-
bc_init_num(&result);
276-
bc_str2num(&first, Z_STRVAL_PP(left), scale);
277-
bc_str2num(&second, Z_STRVAL_PP(right), scale);
278-
switch (bc_divide (first, second, &result, scale)) {
269+
bc_init_num(&first TSRMLS_CC);
270+
bc_init_num(&second TSRMLS_CC);
271+
bc_init_num(&result TSRMLS_CC);
272+
bc_str2num(&first, Z_STRVAL_PP(left), scale TSRMLS_CC);
273+
bc_str2num(&second, Z_STRVAL_PP(right), scale TSRMLS_CC);
274+
switch (bc_divide (first, second, &result, scale TSRMLS_CC)) {
279275
case 0: /* OK */
280276
Z_STRVAL_P(return_value) = bc_num2str(result);
281277
Z_STRLEN_P(return_value) = strlen(Z_STRVAL_P(return_value));
@@ -311,12 +307,12 @@ PHP_FUNCTION(bcmod)
311307
}
312308
convert_to_string_ex(left);
313309
convert_to_string_ex(right);
314-
bc_init_num(&first);
315-
bc_init_num(&second);
316-
bc_init_num(&result);
317-
bc_str2num(&first, Z_STRVAL_PP(left), 0);
318-
bc_str2num(&second, Z_STRVAL_PP(right), 0);
319-
switch (bc_modulo(first, second, &result, 0)) {
310+
bc_init_num(&first TSRMLS_CC);
311+
bc_init_num(&second TSRMLS_CC);
312+
bc_init_num(&result TSRMLS_CC);
313+
bc_str2num(&first, Z_STRVAL_PP(left), 0 TSRMLS_CC);
314+
bc_str2num(&second, Z_STRVAL_PP(right), 0 TSRMLS_CC);
315+
switch (bc_modulo(first, second, &result, 0 TSRMLS_CC)) {
320316
case 0:
321317
Z_STRVAL_P(return_value) = bc_num2str(result);
322318
Z_STRLEN_P(return_value) = strlen(Z_STRVAL_P(return_value));
@@ -360,12 +356,12 @@ PHP_FUNCTION(bcpow)
360356
}
361357
convert_to_string_ex(left);
362358
convert_to_string_ex(right);
363-
bc_init_num(&first);
364-
bc_init_num(&second);
365-
bc_init_num(&result);
366-
bc_str2num(&first, Z_STRVAL_PP(left), scale);
367-
bc_str2num(&second, Z_STRVAL_PP(right), scale);
368-
bc_raise (first, second, &result, scale);
359+
bc_init_num(&first TSRMLS_CC);
360+
bc_init_num(&second TSRMLS_CC);
361+
bc_init_num(&result TSRMLS_CC);
362+
bc_str2num(&first, Z_STRVAL_PP(left), scale TSRMLS_CC);
363+
bc_str2num(&second, Z_STRVAL_PP(right), scale TSRMLS_CC);
364+
bc_raise (first, second, &result, scale TSRMLS_CC);
369365
Z_STRVAL_P(return_value) = bc_num2str(result);
370366
Z_STRLEN_P(return_value) = strlen(Z_STRVAL_P(return_value));
371367
Z_TYPE_P(return_value) = IS_STRING;
@@ -402,9 +398,9 @@ PHP_FUNCTION(bcsqrt)
402398
break;
403399
}
404400
convert_to_string_ex(left);
405-
bc_init_num(&result);
406-
bc_str2num(&result, Z_STRVAL_PP(left), scale);
407-
if (bc_sqrt (&result, scale) != 0) {
401+
bc_init_num(&result TSRMLS_CC);
402+
bc_str2num(&result, Z_STRVAL_PP(left), scale TSRMLS_CC);
403+
if (bc_sqrt (&result, scale TSRMLS_CC) != 0) {
408404
Z_STRVAL_P(return_value) = bc_num2str(result);
409405
Z_STRLEN_P(return_value) = strlen(Z_STRVAL_P(return_value));
410406
Z_TYPE_P(return_value) = IS_STRING;
@@ -444,11 +440,11 @@ PHP_FUNCTION(bccomp)
444440

445441
convert_to_string_ex(left);
446442
convert_to_string_ex(right);
447-
bc_init_num(&first);
448-
bc_init_num(&second);
443+
bc_init_num(&first TSRMLS_CC);
444+
bc_init_num(&second TSRMLS_CC);
449445

450-
bc_str2num(&first, Z_STRVAL_PP(left), scale);
451-
bc_str2num(&second, Z_STRVAL_PP(right), scale);
446+
bc_str2num(&first, Z_STRVAL_PP(left), scale TSRMLS_CC);
447+
bc_str2num(&second, Z_STRVAL_PP(right), scale TSRMLS_CC);
452448
Z_LVAL_P(return_value) = bc_compare(first, second);
453449
Z_TYPE_P(return_value) = IS_LONG;
454450

ext/bcmath/libbcmath/src/bcmath.h

Lines changed: 15 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,9 @@ typedef struct bc_struct
5252
in the case of leading zeros generated. */
5353
} bc_struct;
5454

55+
#include <php.h>
56+
#include <ext/bcmath/php_bcmath.h>
57+
5558

5659
/* The base used in storing the numbers in n_value above.
5760
Currently this MUST be 10. */
@@ -81,12 +84,6 @@ typedef struct bc_struct
8184
#endif
8285

8386

84-
/* Global numbers. */
85-
extern bc_num _zero_;
86-
extern bc_num _one_;
87-
extern bc_num _two_;
88-
89-
9087
/* Function Prototypes */
9188

9289
/* Define the _PROTOTYPE macro if it is needed. */
@@ -99,17 +96,17 @@ extern bc_num _two_;
9996
#endif
10097
#endif
10198

102-
_PROTOTYPE(void bc_init_numbers, (void));
99+
_PROTOTYPE(void bc_init_numbers, (TSRMLS_D));
103100

104101
_PROTOTYPE(bc_num bc_new_num, (int length, int scale));
105102

106103
_PROTOTYPE(void bc_free_num, (bc_num *num));
107104

108105
_PROTOTYPE(bc_num bc_copy_num, (bc_num num));
109106

110-
_PROTOTYPE(void bc_init_num, (bc_num *num));
107+
_PROTOTYPE(void bc_init_num, (bc_num *num TSRMLS_DC));
111108

112-
_PROTOTYPE(void bc_str2num, (bc_num *num, char *str, int scale));
109+
_PROTOTYPE(void bc_str2num, (bc_num *num, char *str, int scale TSRMLS_DC));
113110

114111
_PROTOTYPE(char *bc_num2str, (bc_num num));
115112

@@ -119,7 +116,7 @@ _PROTOTYPE(long bc_num2long, (bc_num num));
119116

120117
_PROTOTYPE(int bc_compare, (bc_num n1, bc_num n2));
121118

122-
_PROTOTYPE(char bc_is_zero, (bc_num num));
119+
_PROTOTYPE(char bc_is_zero, (bc_num num TSRMLS_DC));
123120

124121
_PROTOTYPE(char bc_is_near_zero, (bc_num num, int scale));
125122

@@ -129,26 +126,26 @@ _PROTOTYPE(void bc_add, (bc_num n1, bc_num n2, bc_num *result, int scale_min));
129126

130127
_PROTOTYPE(void bc_sub, (bc_num n1, bc_num n2, bc_num *result, int scale_min));
131128

132-
_PROTOTYPE(void bc_multiply, (bc_num n1, bc_num n2, bc_num *prod, int scale));
129+
_PROTOTYPE(void bc_multiply, (bc_num n1, bc_num n2, bc_num *prod, int scale TSRMLS_DC));
133130

134-
_PROTOTYPE(int bc_divide, (bc_num n1, bc_num n2, bc_num *quot, int scale));
131+
_PROTOTYPE(int bc_divide, (bc_num n1, bc_num n2, bc_num *quot, int scale TSRMLS_DC));
135132

136133
_PROTOTYPE(int bc_modulo, (bc_num num1, bc_num num2, bc_num *result,
137-
int scale));
134+
int scale TSRMLS_DC));
138135

139136
_PROTOTYPE(int bc_divmod, (bc_num num1, bc_num num2, bc_num *quot,
140-
bc_num *rem, int scale));
137+
bc_num *rem, int scale TSRMLS_DC));
141138

142139
_PROTOTYPE(int bc_raisemod, (bc_num base, bc_num expo, bc_num mod,
143-
bc_num *result, int scale));
140+
bc_num *result, int scale TSRMLS_DC));
144141

145142
_PROTOTYPE(void bc_raise, (bc_num num1, bc_num num2, bc_num *result,
146-
int scale));
143+
int scale TSRMLS_DC));
147144

148-
_PROTOTYPE(int bc_sqrt, (bc_num *num, int scale));
145+
_PROTOTYPE(int bc_sqrt, (bc_num *num, int scale TSRMLS_DC));
149146

150147
_PROTOTYPE(void bc_out_num, (bc_num num, int o_base, void (* out_char)(int),
151-
int leading_zero));
148+
int leading_zero TSRMLS_DC));
152149

153150
/* Prototypes needed for external utility routines. */
154151

ext/bcmath/libbcmath/src/debug.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,10 +48,9 @@ out_char (int c)
4848

4949

5050
void
51-
pn (num)
52-
bc_num num;
51+
pn (bc_num num TSRMLS_DC)
5352
{
54-
bc_out_num (num, 10, out_char, 0);
53+
bc_out_num (num, 10, out_char, 0 TSRMLS_CC);
5554
out_char ('\n');
5655
}
5756

ext/bcmath/libbcmath/src/div.c

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -85,9 +85,7 @@ _one_mult (num, size, digit, result)
8585
by zero is tried. The algorithm is found in Knuth Vol 2. p237. */
8686

8787
int
88-
bc_divide (n1, n2, quot, scale)
89-
bc_num n1, n2, *quot;
90-
int scale;
88+
bc_divide (bc_num n1, bc_num n2, bc_num *quot, int scale TSRMLS_DC)
9189
{
9290
bc_num qval;
9391
unsigned char *num1, *num2;
@@ -100,7 +98,7 @@ bc_divide (n1, n2, quot, scale)
10098
unsigned int norm;
10199

102100
/* Test for divide by zero. */
103-
if (bc_is_zero (n2)) return -1;
101+
if (bc_is_zero (n2 TSRMLS_CC)) return -1;
104102

105103
/* Test for divide by 1. If it is we must truncate. */
106104
if (n2->n_scale == 0)
@@ -261,7 +259,7 @@ bc_divide (n1, n2, quot, scale)
261259

262260
/* Clean up and return the number. */
263261
qval->n_sign = ( n1->n_sign == n2->n_sign ? PLUS : MINUS );
264-
if (bc_is_zero (qval)) qval->n_sign = PLUS;
262+
if (bc_is_zero (qval TSRMLS_CC)) qval->n_sign = PLUS;
265263
_bc_rm_leading_zeros (qval);
266264
bc_free_num (quot);
267265
*quot = qval;

ext/bcmath/libbcmath/src/divmod.c

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -45,26 +45,24 @@
4545
*/
4646

4747
int
48-
bc_divmod (num1, num2, quot, rem, scale)
49-
bc_num num1, num2, *quot, *rem;
50-
int scale;
48+
bc_divmod (bc_num num1, bc_num num2, bc_num *quot, bc_num *rem, int scale TSRMLS_DC)
5149
{
5250
bc_num quotient = NULL;
5351
bc_num temp;
5452
int rscale;
5553

5654
/* Check for correct numbers. */
57-
if (bc_is_zero (num2)) return -1;
55+
if (bc_is_zero (num2 TSRMLS_CC)) return -1;
5856

5957
/* Calculate final scale. */
6058
rscale = MAX (num1->n_scale, num2->n_scale+scale);
61-
bc_init_num(&temp);
59+
bc_init_num(&temp TSRMLS_CC);
6260

6361
/* Calculate it. */
64-
bc_divide (num1, num2, &temp, scale);
62+
bc_divide (num1, num2, &temp, scale TSRMLS_CC);
6563
if (quot)
6664
quotient = bc_copy_num (temp);
67-
bc_multiply (temp, num2, &temp, rscale);
65+
bc_multiply (temp, num2, &temp, rscale TSRMLS_CC);
6866
bc_sub (num1, temp, rem, rscale);
6967
bc_free_num (&temp);
7068

@@ -82,10 +80,8 @@ bc_divmod (num1, num2, quot, rem, scale)
8280
result in RESULT. */
8381

8482
int
85-
bc_modulo (num1, num2, result, scale)
86-
bc_num num1, num2, *result;
87-
int scale;
83+
bc_modulo (bc_num num1, bc_num num2, bc_num *result, int scale TSRMLS_DC)
8884
{
89-
return bc_divmod (num1, num2, NULL, result, scale);
85+
return bc_divmod (num1, num2, NULL, result, scale TSRMLS_CC);
9086
}
9187

0 commit comments

Comments
 (0)