@@ -50,6 +50,7 @@ struct ThreadObject {
50
50
};
51
51
52
52
static void php_swoole_thread_join (zend_object *object);
53
+ static void php_swoole_thread_create (INTERNAL_FUNCTION_PARAMETERS, zval *zobject);
53
54
54
55
static thread_local zval thread_argv;
55
56
static zend_long thread_resource_id = 0 ;
@@ -147,7 +148,9 @@ void php_swoole_thread_minit(int module_number) {
147
148
swoole_thread_ce, ZEND_STRL (" HARDWARE_CONCURRENCY" ), std::thread::hardware_concurrency ());
148
149
}
149
150
150
- static PHP_METHOD (swoole_thread, __construct) {}
151
+ static PHP_METHOD (swoole_thread, __construct) {
152
+ php_swoole_thread_create (INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_THIS);
153
+ }
151
154
152
155
static PHP_METHOD (swoole_thread, join) {
153
156
ThreadObject *to = php_swoole_thread_fetch_object (Z_OBJ_P (ZEND_THIS));
@@ -252,6 +255,42 @@ void php_swoole_thread_rshutdown() {
252
255
}
253
256
}
254
257
258
+ static void php_swoole_thread_create (INTERNAL_FUNCTION_PARAMETERS, zval *zobject) {
259
+ char *script_file;
260
+ size_t l_script_file;
261
+ zval *args;
262
+ int argc;
263
+
264
+ ZEND_PARSE_PARAMETERS_START (1 , -1 )
265
+ Z_PARAM_STRING (script_file, l_script_file)
266
+ Z_PARAM_VARIADIC (' +' , args, argc)
267
+ ZEND_PARSE_PARAMETERS_END ();
268
+
269
+ if (l_script_file < 1 ) {
270
+ zend_throw_exception (swoole_exception_ce, " exec file name is empty" , SW_ERROR_INVALID_PARAMS);
271
+ return ;
272
+ }
273
+
274
+ ThreadObject *to = php_swoole_thread_fetch_object (Z_OBJ_P (zobject));
275
+ zend_string *file = zend_string_init (script_file, l_script_file, 1 );
276
+
277
+ zval zargv;
278
+ array_init (&zargv);
279
+ for (int i = 0 ; i < argc; i++) {
280
+ zend::array_add (&zargv, &args[i]);
281
+ }
282
+ zend_string *argv = php_swoole_thread_serialize (&zargv);
283
+ zval_dtor (&zargv);
284
+
285
+ if (!argv) {
286
+ zend_string_release (file);
287
+ return ;
288
+ }
289
+
290
+ to->thread = new std::thread ([file, argv]() { php_swoole_thread_start (file, argv); });
291
+ zend_update_property_long (swoole_thread_ce, SW_Z8_OBJ_P (zobject), ZEND_STRL (" id" ), to->thread ->native_handle ());
292
+ }
293
+
255
294
void php_swoole_thread_start (zend_string *file, zend_string *argv_serialized) {
256
295
ts_resource (0 );
257
296
TSRMLS_CACHE_UPDATE ();
@@ -311,41 +350,8 @@ void php_swoole_thread_start(zend_string *file, zend_string *argv_serialized) {
311
350
}
312
351
313
352
static PHP_METHOD (swoole_thread, exec) {
314
- char *script_file;
315
- size_t l_script_file;
316
- zval *args;
317
- int argc;
318
-
319
- ZEND_PARSE_PARAMETERS_START (1 , -1 )
320
- Z_PARAM_STRING (script_file, l_script_file)
321
- Z_PARAM_VARIADIC (' +' , args, argc)
322
- ZEND_PARSE_PARAMETERS_END ();
323
-
324
- if (l_script_file < 1 ) {
325
- php_swoole_fatal_error (E_WARNING, " exec file name is empty" );
326
- RETURN_FALSE;
327
- }
328
-
329
353
object_init_ex (return_value, swoole_thread_ce);
330
- ThreadObject *to = php_swoole_thread_fetch_object (Z_OBJ_P (return_value));
331
- zend_string *file = zend_string_init (script_file, l_script_file, 1 );
332
-
333
- zval zargv;
334
- array_init (&zargv);
335
- for (int i = 0 ; i < argc; i++) {
336
- zend::array_add (&zargv, &args[i]);
337
- }
338
- zend_string *argv = php_swoole_thread_serialize (&zargv);
339
- zval_dtor (&zargv);
340
-
341
- if (!argv) {
342
- zend_string_release (file);
343
- return ;
344
- }
345
-
346
- to->thread = new std::thread ([file, argv]() { php_swoole_thread_start (file, argv); });
347
- zend_update_property_long (
348
- swoole_thread_ce, SW_Z8_OBJ_P (return_value), ZEND_STRL (" id" ), to->thread ->native_handle ());
354
+ php_swoole_thread_create (INTERNAL_FUNCTION_PARAM_PASSTHRU, return_value);
349
355
}
350
356
351
357
static PHP_METHOD (swoole_thread, getTsrmInfo) {
@@ -355,4 +361,96 @@ static PHP_METHOD(swoole_thread, getTsrmInfo) {
355
361
add_assoc_string (return_value, " api_name" , tsrm_api_name ());
356
362
}
357
363
364
+ void ArrayItem::store (zval *zvalue) {
365
+ type = Z_TYPE_P (zvalue);
366
+ switch (type) {
367
+ case IS_LONG:
368
+ value.lval = zval_get_long (zvalue);
369
+ break ;
370
+ case IS_DOUBLE:
371
+ value.dval = zval_get_double (zvalue);
372
+ break ;
373
+ case IS_STRING: {
374
+ value.str = zend_string_init (Z_STRVAL_P (zvalue), Z_STRLEN_P (zvalue), 1 );
375
+ break ;
376
+ }
377
+ case IS_TRUE:
378
+ case IS_FALSE:
379
+ case IS_NULL:
380
+ break ;
381
+ case IS_RESOURCE: {
382
+ php_stream *stream;
383
+ int sock_fd;
384
+ int cast_flags = PHP_STREAM_AS_FD_FOR_SELECT | PHP_STREAM_CAST_INTERNAL;
385
+ if ((php_stream_from_zval_no_verify (stream, zvalue))) {
386
+ if (php_stream_cast (stream, cast_flags, (void **) &sock_fd, 1 ) == SUCCESS && sock_fd >= 0 ) {
387
+ value.lval = dup (sock_fd);
388
+ if (value.lval != -1 ) {
389
+ type = IS_STREAM_SOCKET;
390
+ break ;
391
+ }
392
+ }
393
+ }
394
+ }
395
+ /* no break */
396
+ default : {
397
+ auto _serialized_object = php_swoole_thread_serialize (zvalue);
398
+ if (!_serialized_object) {
399
+ type = IS_UNDEF;
400
+ break ;
401
+ } else {
402
+ type = IS_SERIALIZED_OBJECT;
403
+ value.serialized_object = _serialized_object;
404
+ }
405
+ break ;
406
+ }
407
+ }
408
+ }
409
+
410
+ void ArrayItem::fetch (zval *return_value) {
411
+ switch (type) {
412
+ case IS_LONG:
413
+ RETVAL_LONG (value.lval );
414
+ break ;
415
+ case IS_DOUBLE:
416
+ RETVAL_LONG (value.dval );
417
+ break ;
418
+ case IS_TRUE:
419
+ RETVAL_TRUE;
420
+ break ;
421
+ case IS_FALSE:
422
+ RETVAL_FALSE;
423
+ break ;
424
+ case IS_STRING:
425
+ RETVAL_NEW_STR (zend_string_init (ZSTR_VAL (value.str ), ZSTR_LEN (value.str ), 0 ));
426
+ break ;
427
+ case IS_STREAM_SOCKET: {
428
+ std::string path = " php://fd/" + std::to_string (value.lval );
429
+ php_stream *stream = php_stream_open_wrapper_ex (path.c_str (), " " , 0 , NULL , NULL );
430
+ if (stream) {
431
+ php_stream_to_zval (stream, return_value);
432
+ }
433
+ break ;
434
+ }
435
+ case IS_SERIALIZED_OBJECT:
436
+ php_swoole_thread_unserialize (value.serialized_object , return_value);
437
+ break ;
438
+ default :
439
+ break ;
440
+ }
441
+ }
442
+
443
+ void ArrayItem::release () {
444
+ if (type == IS_STRING) {
445
+ zend_string_release (value.str );
446
+ value.str = nullptr ;
447
+ } else if (type == IS_STREAM_SOCKET) {
448
+ ::close (value.lval);
449
+ value.lval = -1 ;
450
+ } else if (type == IS_SERIALIZED_OBJECT) {
451
+ zend_string_release (value.serialized_object );
452
+ value.serialized_object = nullptr ;
453
+ }
454
+ }
455
+
358
456
#endif
0 commit comments