diff --git a/async.c b/async.c index 6f2de71..a9afdaf 100644 --- a/async.c +++ b/async.c @@ -29,9 +29,7 @@ #include "async_API.h" #include "async_arginfo.h" #include "zend_interfaces.h" -#ifdef PHP_ASYNC_LIBUV #include "libuv_reactor.h" -#endif zend_class_entry *async_ce_awaitable = NULL; zend_class_entry *async_ce_timeout = NULL; @@ -889,8 +887,6 @@ static PHP_GINIT_FUNCTION(async) #endif async_globals->reactor_started = false; - -#ifdef PHP_ASYNC_LIBUV async_globals->signal_handlers = NULL; async_globals->signal_events = NULL; async_globals->process_events = NULL; @@ -906,7 +902,6 @@ static PHP_GINIT_FUNCTION(async) async_globals->uvloop_wakeup = NULL; async_globals->pid_queue = NULL; #endif -#endif } /* {{{ PHP_GSHUTDOWN_FUNCTION */ @@ -932,12 +927,8 @@ ZEND_MINIT_FUNCTION(async) // async_register_future_ce(); async_scheduler_startup(); - async_api_register(); - -#ifdef PHP_ASYNC_LIBUV async_libuv_reactor_register(); -#endif return SUCCESS; } @@ -945,10 +936,7 @@ ZEND_MINIT_FUNCTION(async) ZEND_MSHUTDOWN_FUNCTION(async) { // async_scheduler_shutdown(); - -#ifdef PHP_ASYNC_LIBUV // async_libuv_shutdown(); -#endif return SUCCESS; } @@ -959,11 +947,7 @@ PHP_MINFO_FUNCTION(async) php_info_print_table_header(2, "Module", PHP_ASYNC_NAME); php_info_print_table_row(2, "Version", PHP_ASYNC_VERSION); php_info_print_table_row(2, "Support", "Enabled"); -#ifdef PHP_ASYNC_LIBUV php_info_print_table_row(2, "LibUv Reactor", "Enabled"); -#else - php_info_print_table_row(2, "LibUv Reactor", "Disabled"); -#endif php_info_print_table_end(); } diff --git a/config.m4 b/config.m4 index 11dd57e..95c0c0c 100644 --- a/config.m4 +++ b/config.m4 @@ -11,7 +11,7 @@ if test "$PHP_ASYNC" = "yes"; then dnl Register extension source files. PHP_NEW_EXTENSION([async], [async.c coroutine.c scope.c scheduler.c exceptions.c iterator.c async_API.c \ - context.c \ + context.c libuv_reactor.c \ internal/allocator.c internal/circular_buffer.c \ zend_common.c], $ext_shared) @@ -32,7 +32,6 @@ if test "$PHP_ASYNC" = "yes"; then LIBUV_LIBLINE=`$PKG_CONFIG libuv --libs` LIBUV_VERSION=`$PKG_CONFIG libuv --modversion` AC_MSG_RESULT(from pkgconfig: found version $LIBUV_VERSION) - AC_DEFINE(PHP_ASYNC_LIBUV,1,[ ]) else AC_MSG_ERROR(system libuv must be upgraded to version >= 1.44.0 (fixes UV_RUN_ONCE busy loop issue)) fi @@ -57,7 +56,6 @@ if test "$PHP_ASYNC" = "yes"; then PHP_CHECK_LIBRARY(uv, uv_version, [ PHP_ADD_LIBRARY_WITH_PATH(uv, $UV_DIR/$PHP_LIBDIR, UV_SHARED_LIBADD) - AC_DEFINE(PHP_ASYNC_LIBUV,1,[ ]) ],[ AC_MSG_ERROR([wrong uv library version or library not found]) ],[ @@ -74,8 +72,8 @@ if test "$PHP_ASYNC" = "yes"; then dnl Link against needed libraries. PHP_ADD_LIBRARY([uv], 1, ASYNC_SHARED_LIBADD) + PHP_SUBST(ASYNC_SHARED_LIBADD) - dnl Add libuv-specific reactor code. - PHP_ADD_SOURCES([ext/async], [libuv_reactor.c]) + dnl Install libuv-specific reactor headers. PHP_INSTALL_HEADERS([ext/async], [libuv_reactor.h]) fi diff --git a/config.w32 b/config.w32 index 890e920..a076316 100644 --- a/config.w32 +++ b/config.w32 @@ -4,19 +4,11 @@ ARG_ENABLE('async', 'Enable True Async', 'no'); if (PHP_ASYNC == "yes") { - if(typeof PHP_ASYNC_API == "undefined" && typeof PHP_EXPERIMENTAL_ASYNC_API != "undefined") { - var PHP_ASYNC_API = PHP_EXPERIMENTAL_ASYNC_API; - } - - if (!PHP_ASYNC_API || PHP_ASYNC_API != "yes") { - ERROR("PHP TRUE ASYNC API is required. Please configure PHP with --with-async-api."); - } - - EXTENSION("async", "async.c coroutine.c scope.c scheduler.c exceptions.c iterator.c async_API.c"); - ADD_SOURCES("ext/async","zend_common.c context.c"); + EXTENSION("async", "async.c coroutine.c scope.c scheduler.c exceptions.c iterator.c async_API.c zend_common.c context.c libuv_reactor.c"); ADD_SOURCES("ext/async/internal", "allocator.c circular_buffer.c"); ADD_FLAG("CFLAGS", "/D PHP_ASYNC"); + ADD_FLAG("CFLAGS", "/D ASYNC_EXPORTS"); PHP_INSTALL_HEADERS("ext/async", "php_async.h"); PHP_INSTALL_HEADERS("ext/async", "coroutine.h"); @@ -26,17 +18,14 @@ if (PHP_ASYNC == "yes") { PHP_INSTALL_HEADERS("ext/async", "iterator.h"); PHP_INSTALL_HEADERS("ext/async", "async_API.h"); PHP_INSTALL_HEADERS("ext/async", "context.h"); + PHP_INSTALL_HEADERS("ext/async", "libuv_reactor.h"); if (CHECK_HEADER_ADD_INCLUDE("libuv/uv.h", "CFLAGS_UV", PHP_PHP_BUILD + "\\include") && CHECK_LIB("libuv.lib", "libuv")) { // Note: libuv >= 1.44.0 is required for UV_RUN_ONCE busy loop fix // For Windows builds, manually verify libuv version meets requirements - - PHP_INSTALL_HEADERS("ext/async", "libuv_reactor.h"); - ADD_SOURCES("ext/async", "libuv_reactor.c"); - ADD_FLAG("CFLAGS", "/D PHP_ASYNC_LIBUV"); ADD_FLAG("LIBS", "libuv.lib Dbghelp.lib Userenv.lib"); } else { ERROR("Libuv components are not found. The search was performed in the directory: '" + PHP_PHP_BUILD + diff --git a/context.h b/context.h index 767bb91..1d5aeb3 100644 --- a/context.h +++ b/context.h @@ -16,6 +16,7 @@ #ifndef CONTEXT_H #define CONTEXT_H +#include "php_async.h" #include typedef struct _async_context_s async_context_t; @@ -40,7 +41,7 @@ async_context_t *async_context_new(void); void async_context_dispose(async_context_t *context); // Class entry -extern zend_class_entry *async_ce_context; +PHP_ASYNC_API extern zend_class_entry *async_ce_context; void async_register_context_ce(void); diff --git a/coroutine.h b/coroutine.h index e4affea..ca2ca2b 100644 --- a/coroutine.h +++ b/coroutine.h @@ -16,10 +16,11 @@ #ifndef COROUTINE_H #define COROUTINE_H +#include "php_async_api.h" #include ZEND_STACK_ALIGNED void async_coroutine_execute(zend_fiber_transfer *transfer); -extern zend_class_entry *async_ce_coroutine; +PHP_ASYNC_API extern zend_class_entry *async_ce_coroutine; typedef struct _async_coroutine_s async_coroutine_t; diff --git a/exceptions.c b/exceptions.c index 164cf62..4093263 100644 --- a/exceptions.c +++ b/exceptions.c @@ -13,6 +13,7 @@ | Author: Edmond | +----------------------------------------------------------------------+ */ +#include "php_async.h" #include "exceptions.h" #include @@ -68,7 +69,7 @@ void async_register_exceptions_ce(void) async_ce_composite_exception = register_class_Async_CompositeException(zend_ce_exception); } -zend_object *async_new_exception(zend_class_entry *exception_ce, const char *format, ...) +PHP_ASYNC_API zend_object *async_new_exception(zend_class_entry *exception_ce, const char *format, ...) { zval exception, message_val; @@ -95,7 +96,7 @@ zend_object *async_new_exception(zend_class_entry *exception_ce, const char *for return Z_OBJ(exception); } -ZEND_API ZEND_COLD zend_object *async_throw_error(const char *format, ...) +PHP_ASYNC_API ZEND_COLD zend_object *async_throw_error(const char *format, ...) { va_list args; va_start(args, format); @@ -115,7 +116,7 @@ ZEND_API ZEND_COLD zend_object *async_throw_error(const char *format, ...) return obj; } -ZEND_API ZEND_COLD zend_object *async_throw_cancellation(const char *format, ...) +PHP_ASYNC_API ZEND_COLD zend_object *async_throw_cancellation(const char *format, ...) { const zend_object *previous_exception = EG(exception); @@ -142,7 +143,7 @@ ZEND_API ZEND_COLD zend_object *async_throw_cancellation(const char *format, ... return obj; } -ZEND_API ZEND_COLD zend_object *async_throw_input_output(const char *format, ...) +PHP_ASYNC_API ZEND_COLD zend_object *async_throw_input_output(const char *format, ...) { format = format ? format : "An input/output error occurred."; @@ -162,7 +163,7 @@ ZEND_API ZEND_COLD zend_object *async_throw_input_output(const char *format, ... return obj; } -ZEND_API ZEND_COLD zend_object *async_throw_timeout(const char *format, const zend_long timeout) +PHP_ASYNC_API ZEND_COLD zend_object *async_throw_timeout(const char *format, const zend_long timeout) { format = format ? format : "A timeout of %u microseconds occurred"; @@ -175,7 +176,7 @@ ZEND_API ZEND_COLD zend_object *async_throw_timeout(const char *format, const ze } } -ZEND_API ZEND_COLD zend_object *async_throw_poll(const char *format, ...) +PHP_ASYNC_API ZEND_COLD zend_object *async_throw_poll(const char *format, ...) { va_list args; va_start(args, format); @@ -193,15 +194,14 @@ ZEND_API ZEND_COLD zend_object *async_throw_poll(const char *format, ...) return obj; } -ZEND_API ZEND_COLD zend_object *async_new_composite_exception(void) +PHP_ASYNC_API ZEND_COLD zend_object *async_new_composite_exception(void) { zval composite; object_init_ex(&composite, async_ce_composite_exception); return Z_OBJ(composite); } -ZEND_API ZEND_COLD void -async_composite_exception_add_exception(zend_object *composite, zend_object *exception, bool transfer) +PHP_ASYNC_API void async_composite_exception_add_exception(zend_object *composite, zend_object *exception, bool transfer) { if (composite == NULL || exception == NULL) { return; @@ -321,7 +321,7 @@ void async_apply_exception(zend_object **to_exception) } } -void async_rethrow_exception(zend_object *exception) +PHP_ASYNC_API void async_rethrow_exception(zend_object *exception) { if (EG(current_execute_data)) { zend_throw_exception_internal(exception); diff --git a/exceptions.h b/exceptions.h index 33395f5..db7ca7c 100644 --- a/exceptions.h +++ b/exceptions.h @@ -19,30 +19,31 @@ #include #include #include +#include "php_async_api.h" BEGIN_EXTERN_C() -extern zend_class_entry *async_ce_async_exception; -extern zend_class_entry *async_ce_cancellation_exception; -extern zend_class_entry *async_ce_input_output_exception; -extern zend_class_entry *async_ce_timeout_exception; -extern zend_class_entry *async_ce_poll_exception; -extern zend_class_entry *async_ce_dns_exception; -extern zend_class_entry *async_ce_composite_exception; +PHP_ASYNC_API extern zend_class_entry *async_ce_async_exception; +PHP_ASYNC_API extern zend_class_entry *async_ce_cancellation_exception; +PHP_ASYNC_API extern zend_class_entry *async_ce_input_output_exception; +PHP_ASYNC_API extern zend_class_entry *async_ce_timeout_exception; +PHP_ASYNC_API extern zend_class_entry *async_ce_poll_exception; +PHP_ASYNC_API extern zend_class_entry *async_ce_dns_exception; +PHP_ASYNC_API extern zend_class_entry *async_ce_composite_exception; void async_register_exceptions_ce(void); -ZEND_API ZEND_COLD zend_object *async_new_exception(zend_class_entry *exception_ce, const char *format, ...); -ZEND_API ZEND_COLD zend_object *async_throw_error(const char *format, ...); -ZEND_API ZEND_COLD zend_object *async_throw_cancellation(const char *format, ...); -ZEND_API ZEND_COLD zend_object *async_throw_input_output(const char *format, ...); -ZEND_API ZEND_COLD zend_object *async_throw_timeout(const char *format, const zend_long timeout); -ZEND_API ZEND_COLD zend_object *async_throw_poll(const char *format, ...); -ZEND_API ZEND_COLD zend_object *async_new_composite_exception(void); -ZEND_API void async_composite_exception_add_exception(zend_object *composite, zend_object *exception, bool transfer); +PHP_ASYNC_API ZEND_COLD zend_object *async_new_exception(zend_class_entry *exception_ce, const char *format, ...); +PHP_ASYNC_API ZEND_COLD zend_object *async_throw_error(const char *format, ...); +PHP_ASYNC_API ZEND_COLD zend_object *async_throw_cancellation(const char *format, ...); +PHP_ASYNC_API ZEND_COLD zend_object *async_throw_input_output(const char *format, ...); +PHP_ASYNC_API ZEND_COLD zend_object *async_throw_timeout(const char *format, const zend_long timeout); +PHP_ASYNC_API ZEND_COLD zend_object *async_throw_poll(const char *format, ...); +PHP_ASYNC_API ZEND_COLD zend_object *async_new_composite_exception(void); +PHP_ASYNC_API void async_composite_exception_add_exception(zend_object *composite, zend_object *exception, bool transfer); bool async_spawn_and_throw(zend_object *exception, zend_async_scope_t *scope, int32_t priority); void async_apply_exception_to_context(zend_object *exception); zend_object *async_extract_exception(void); -void async_rethrow_exception(zend_object *exception); +PHP_ASYNC_API void async_rethrow_exception(zend_object *exception); void async_apply_exception(zend_object **to_exception); END_EXTERN_C() diff --git a/php_async.h b/php_async.h index 124a65f..8f44472 100644 --- a/php_async.h +++ b/php_async.h @@ -18,13 +18,11 @@ #include -#ifdef PHP_ASYNC_LIBUV #ifdef PHP_WIN32 #include "libuv/uv.h" #else #include #endif -#endif #include "coroutine.h" #include "internal/circular_buffer.h" @@ -38,12 +36,14 @@ extern zend_module_entry async_module_entry; #define phpext_async_ptr &async_module_entry -extern zend_class_entry *async_ce_awaitable; -extern zend_class_entry *async_ce_timeout; +#include "php_async_api.h" + +PHP_ASYNC_API extern zend_class_entry *async_ce_awaitable; +PHP_ASYNC_API extern zend_class_entry *async_ce_timeout; -#define PHP_ASYNC_NAME "TrueAsync" -#define PHP_ASYNC_VERSION "0.5.0" -#define PHP_ASYNC_NAME_VERSION "TrueAsync v0.5.0" +#define PHP_ASYNC_NAME "true_async" +#define PHP_ASYNC_VERSION "0.4.0" +#define PHP_ASYNC_NAME_VERSION "true async v0.4.0" typedef struct { @@ -82,7 +82,6 @@ zend_async_context_t *root_context; /* The default concurrency */ int default_concurrency; -#ifdef PHP_ASYNC_LIBUV /* The reactor */ uv_loop_t uvloop; bool reactor_started; @@ -101,7 +100,6 @@ uv_async_t *uvloop_wakeup; /* Circular buffer of libuv_process_t ptr */ circular_buffer_t *pid_queue; #endif -#endif #ifdef PHP_WIN32 #endif diff --git a/php_async_api.h b/php_async_api.h new file mode 100644 index 0000000..e547083 --- /dev/null +++ b/php_async_api.h @@ -0,0 +1,33 @@ +/* ++----------------------------------------------------------------------+ + | Copyright (c) The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | https://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Edmond | + +----------------------------------------------------------------------+ +*/ +#ifndef PHP_ASYNC_API_H +#define PHP_ASYNC_API_H + +#ifdef PHP_WIN32 +# ifdef ASYNC_EXPORTS +# define PHP_ASYNC_API __declspec(dllexport) +# else +# define PHP_ASYNC_API __declspec(dllimport) +# endif +#else +# if defined(__GNUC__) && __GNUC__ >= 4 +# define PHP_ASYNC_API __attribute__ ((visibility("default"))) +# else +# define PHP_ASYNC_API +# endif +#endif + +#endif // PHP_ASYNC_API_H \ No newline at end of file diff --git a/scope.h b/scope.h index 3baf51b..baed803 100644 --- a/scope.h +++ b/scope.h @@ -18,9 +18,9 @@ #include "php_async.h" -extern zend_class_entry *async_ce_scope; -extern zend_class_entry *async_ce_scope_provider; -extern zend_class_entry *async_ce_spawn_strategy; +PHP_ASYNC_API extern zend_class_entry *async_ce_scope; +PHP_ASYNC_API extern zend_class_entry *async_ce_scope_provider; +PHP_ASYNC_API extern zend_class_entry *async_ce_spawn_strategy; #define ASYNC_SCOPE_MAX_RECURSION_DEPTH 64