Skip to content

Commit ac0c633

Browse files
committed
#46: ext/async: implement proper DLL export macros for SHARED builds
Replace ZEND_API with PHP_ASYNC_API macro that correctly handles __declspec(dllexport/dllimport) on Windows and visibility attributes on Linux. Add ASYNC_EXPORTS compilation flag to config.w32. Fixes Windows linker errors when building as shared extension
1 parent 8719108 commit ac0c633

File tree

7 files changed

+48
-31
lines changed

7 files changed

+48
-31
lines changed

config.w32

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ if (PHP_ASYNC == "yes") {
1717
ADD_SOURCES("ext/async/internal", "allocator.c circular_buffer.c");
1818

1919
ADD_FLAG("CFLAGS", "/D PHP_ASYNC");
20+
ADD_FLAG("CFLAGS", "/D ASYNC_EXPORTS");
2021

2122
PHP_INSTALL_HEADERS("ext/async", "php_async.h");
2223
PHP_INSTALL_HEADERS("ext/async", "coroutine.h");

context.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#ifndef CONTEXT_H
1717
#define CONTEXT_H
1818

19+
#include "php_async.h"
1920
#include <Zend/zend_async_API.h>
2021

2122
typedef struct _async_context_s async_context_t;
@@ -40,7 +41,7 @@ async_context_t *async_context_new(void);
4041
void async_context_dispose(async_context_t *context);
4142

4243
// Class entry
43-
extern zend_class_entry *async_ce_context;
44+
PHP_ASYNC_API extern zend_class_entry *async_ce_context;
4445
void async_register_context_ce(void);
4546

4647

coroutine.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,11 @@
1616
#ifndef COROUTINE_H
1717
#define COROUTINE_H
1818

19+
#include "php_async.h"
1920
#include <Zend/zend_async_API.h>
2021

2122
ZEND_STACK_ALIGNED void async_coroutine_execute(zend_fiber_transfer *transfer);
22-
extern zend_class_entry *async_ce_coroutine;
23+
PHP_ASYNC_API extern zend_class_entry *async_ce_coroutine;
2324

2425
typedef struct _async_coroutine_s async_coroutine_t;
2526

exceptions.c

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
| Author: Edmond |
1414
+----------------------------------------------------------------------+
1515
*/
16+
#include "php_async.h"
1617
#include "exceptions.h"
1718

1819
#include <zend_API.h>
@@ -68,7 +69,7 @@ void async_register_exceptions_ce(void)
6869
async_ce_composite_exception = register_class_Async_CompositeException(zend_ce_exception);
6970
}
7071

71-
zend_object *async_new_exception(zend_class_entry *exception_ce, const char *format, ...)
72+
PHP_ASYNC_API zend_object *async_new_exception(zend_class_entry *exception_ce, const char *format, ...)
7273
{
7374
zval exception, message_val;
7475

@@ -95,7 +96,7 @@ zend_object *async_new_exception(zend_class_entry *exception_ce, const char *for
9596
return Z_OBJ(exception);
9697
}
9798

98-
ZEND_API ZEND_COLD zend_object *async_throw_error(const char *format, ...)
99+
PHP_ASYNC_API ZEND_COLD zend_object *async_throw_error(const char *format, ...)
99100
{
100101
va_list args;
101102
va_start(args, format);
@@ -115,7 +116,7 @@ ZEND_API ZEND_COLD zend_object *async_throw_error(const char *format, ...)
115116
return obj;
116117
}
117118

118-
ZEND_API ZEND_COLD zend_object *async_throw_cancellation(const char *format, ...)
119+
PHP_ASYNC_API ZEND_COLD zend_object *async_throw_cancellation(const char *format, ...)
119120
{
120121
const zend_object *previous_exception = EG(exception);
121122

@@ -142,7 +143,7 @@ ZEND_API ZEND_COLD zend_object *async_throw_cancellation(const char *format, ...
142143
return obj;
143144
}
144145

145-
ZEND_API ZEND_COLD zend_object *async_throw_input_output(const char *format, ...)
146+
PHP_ASYNC_API ZEND_COLD zend_object *async_throw_input_output(const char *format, ...)
146147
{
147148
format = format ? format : "An input/output error occurred.";
148149

@@ -162,7 +163,7 @@ ZEND_API ZEND_COLD zend_object *async_throw_input_output(const char *format, ...
162163
return obj;
163164
}
164165

165-
ZEND_API ZEND_COLD zend_object *async_throw_timeout(const char *format, const zend_long timeout)
166+
PHP_ASYNC_API ZEND_COLD zend_object *async_throw_timeout(const char *format, const zend_long timeout)
166167
{
167168
format = format ? format : "A timeout of %u microseconds occurred";
168169

@@ -175,7 +176,7 @@ ZEND_API ZEND_COLD zend_object *async_throw_timeout(const char *format, const ze
175176
}
176177
}
177178

178-
ZEND_API ZEND_COLD zend_object *async_throw_poll(const char *format, ...)
179+
PHP_ASYNC_API ZEND_COLD zend_object *async_throw_poll(const char *format, ...)
179180
{
180181
va_list args;
181182
va_start(args, format);
@@ -193,15 +194,14 @@ ZEND_API ZEND_COLD zend_object *async_throw_poll(const char *format, ...)
193194
return obj;
194195
}
195196

196-
ZEND_API ZEND_COLD zend_object *async_new_composite_exception(void)
197+
PHP_ASYNC_API ZEND_COLD zend_object *async_new_composite_exception(void)
197198
{
198199
zval composite;
199200
object_init_ex(&composite, async_ce_composite_exception);
200201
return Z_OBJ(composite);
201202
}
202203

203-
ZEND_API ZEND_COLD void
204-
async_composite_exception_add_exception(zend_object *composite, zend_object *exception, bool transfer)
204+
PHP_ASYNC_API void async_composite_exception_add_exception(zend_object *composite, zend_object *exception, bool transfer)
205205
{
206206
if (composite == NULL || exception == NULL) {
207207
return;

exceptions.h

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -22,23 +22,23 @@
2222

2323
BEGIN_EXTERN_C()
2424

25-
extern zend_class_entry *async_ce_async_exception;
26-
extern zend_class_entry *async_ce_cancellation_exception;
27-
extern zend_class_entry *async_ce_input_output_exception;
28-
extern zend_class_entry *async_ce_timeout_exception;
29-
extern zend_class_entry *async_ce_poll_exception;
30-
extern zend_class_entry *async_ce_dns_exception;
31-
extern zend_class_entry *async_ce_composite_exception;
25+
PHP_ASYNC_API extern zend_class_entry *async_ce_async_exception;
26+
PHP_ASYNC_API extern zend_class_entry *async_ce_cancellation_exception;
27+
PHP_ASYNC_API extern zend_class_entry *async_ce_input_output_exception;
28+
PHP_ASYNC_API extern zend_class_entry *async_ce_timeout_exception;
29+
PHP_ASYNC_API extern zend_class_entry *async_ce_poll_exception;
30+
PHP_ASYNC_API extern zend_class_entry *async_ce_dns_exception;
31+
PHP_ASYNC_API extern zend_class_entry *async_ce_composite_exception;
3232

3333
void async_register_exceptions_ce(void);
34-
ZEND_API ZEND_COLD zend_object *async_new_exception(zend_class_entry *exception_ce, const char *format, ...);
35-
ZEND_API ZEND_COLD zend_object *async_throw_error(const char *format, ...);
36-
ZEND_API ZEND_COLD zend_object *async_throw_cancellation(const char *format, ...);
37-
ZEND_API ZEND_COLD zend_object *async_throw_input_output(const char *format, ...);
38-
ZEND_API ZEND_COLD zend_object *async_throw_timeout(const char *format, const zend_long timeout);
39-
ZEND_API ZEND_COLD zend_object *async_throw_poll(const char *format, ...);
40-
ZEND_API ZEND_COLD zend_object *async_new_composite_exception(void);
41-
ZEND_API void async_composite_exception_add_exception(zend_object *composite, zend_object *exception, bool transfer);
34+
PHP_ASYNC_API ZEND_COLD zend_object *async_new_exception(zend_class_entry *exception_ce, const char *format, ...);
35+
PHP_ASYNC_API ZEND_COLD zend_object *async_throw_error(const char *format, ...);
36+
PHP_ASYNC_API ZEND_COLD zend_object *async_throw_cancellation(const char *format, ...);
37+
PHP_ASYNC_API ZEND_COLD zend_object *async_throw_input_output(const char *format, ...);
38+
PHP_ASYNC_API ZEND_COLD zend_object *async_throw_timeout(const char *format, const zend_long timeout);
39+
PHP_ASYNC_API ZEND_COLD zend_object *async_throw_poll(const char *format, ...);
40+
PHP_ASYNC_API ZEND_COLD zend_object *async_new_composite_exception(void);
41+
PHP_ASYNC_API void async_composite_exception_add_exception(zend_object *composite, zend_object *exception, bool transfer);
4242
bool async_spawn_and_throw(zend_object *exception, zend_async_scope_t *scope, int32_t priority);
4343
void async_apply_exception_to_context(zend_object *exception);
4444
zend_object *async_extract_exception(void);

php_async.h

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,22 @@
3838
extern zend_module_entry async_module_entry;
3939
#define phpext_async_ptr &async_module_entry
4040

41-
extern zend_class_entry *async_ce_awaitable;
42-
extern zend_class_entry *async_ce_timeout;
41+
#ifdef PHP_WIN32
42+
# ifdef ASYNC_EXPORTS
43+
# define PHP_ASYNC_API __declspec(dllexport)
44+
# else
45+
# define PHP_ASYNC_API __declspec(dllimport)
46+
# endif
47+
#else
48+
# if defined(__GNUC__) && __GNUC__ >= 4
49+
# define PHP_ASYNC_API __attribute__ ((visibility("default")))
50+
# else
51+
# define PHP_ASYNC_API
52+
# endif
53+
#endif
54+
55+
PHP_ASYNC_API extern zend_class_entry *async_ce_awaitable;
56+
PHP_ASYNC_API extern zend_class_entry *async_ce_timeout;
4357

4458
#define PHP_ASYNC_NAME "TrueAsync"
4559
#define PHP_ASYNC_VERSION "0.5.0"

scope.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,9 @@
1818

1919
#include "php_async.h"
2020

21-
extern zend_class_entry *async_ce_scope;
22-
extern zend_class_entry *async_ce_scope_provider;
23-
extern zend_class_entry *async_ce_spawn_strategy;
21+
PHP_ASYNC_API extern zend_class_entry *async_ce_scope;
22+
PHP_ASYNC_API extern zend_class_entry *async_ce_scope_provider;
23+
PHP_ASYNC_API extern zend_class_entry *async_ce_spawn_strategy;
2424

2525
#define ASYNC_SCOPE_MAX_RECURSION_DEPTH 64
2626

0 commit comments

Comments
 (0)