Welcome to mirror list, hosted at ThFree Co, Russian Federation.

php_aws_crt.h « ext « aws-crt-php « aws - github.com/nextcloud/3rdparty.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 9393a0b4b21c80dcc7d661696506bc181b7cebf9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171

#ifndef PHP_AWS_CRT_H
#define PHP_AWS_CRT_H

/**
 * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
 * SPDX-License-Identifier: Apache-2.0.
 */

#ifdef HAVE_CONFIG_H
#    include "config.h"
#endif

#include "php.h"

#include "Zend/zend_extensions.h" /* for ZEND_EXTENSION_API_NO */

#include <aws/common/common.h>
#include <aws/common/mutex.h>
#include <aws/common/promise.h>
#include <aws/common/thread.h>

/* ZEND_EXTENSION_API_NO from each branch of the PHP source */
#define AWS_PHP_EXTENSION_API_5_5 220121212
#define AWS_PHP_EXTENSION_API_5_6 220131226
#define AWS_PHP_EXTENSION_API_7_0 320151012
#define AWS_PHP_EXTENSION_API_7_1 320160303
#define AWS_PHP_EXTENSION_API_7_2 320170718
#define AWS_PHP_EXTENSION_API_7_3 320180731
#define AWS_PHP_EXTENSION_API_7_4 320190902
#define AWS_PHP_EXTENSION_API_8_0 420200930

#if ZEND_EXTENSION_API_NO < AWS_PHP_EXTENSION_API_5_5
#    error "PHP >= 5.5 is required"
#endif

#define AWS_PHP_AT_LEAST_7 (ZEND_EXTENSION_API_NO >= AWS_PHP_EXTENSION_API_7_0)
#define AWS_PHP_AT_LEAST_7_2 (ZEND_EXTENSION_API_NO >= AWS_PHP_EXTENSION_API_7_2)

ZEND_BEGIN_MODULE_GLOBALS(awscrt)
long log_level;
ZEND_END_MODULE_GLOBALS(awscrt)

ZEND_EXTERN_MODULE_GLOBALS(awscrt)

#define AWSCRT_GLOBAL(v) ZEND_MODULE_GLOBALS_ACCESSOR(awscrt, v)

#if AWS_PHP_AT_LEAST_7
/* PHP 7 takes a zval*, PHP5 takes a zval** */
#    define AWS_PHP_STREAM_FROM_ZVAL(s, z) php_stream_from_zval(s, z)
#define XRETURN_STRINGL RETURN_STRINGL
#define XRETURN_STRING RETURN_STRING
#define XRETVAL_STRINGL RETVAL_STRINGL
#define XRETVAL_STRING RETVAL_STRING
#else /* PHP 5.5-5.6 */
#    define AWS_PHP_STREAM_FROM_ZVAL(s, z) php_stream_from_zval(s, &z)
#define XRETURN_STRINGL(s, l) RETURN_STRINGL(s, l, 1)
#define XRETURN_STRING(s) RETURN_STRING(s, 1)
#define XRETVAL_STRINGL(s, l) RETVAL_STRINGL(s, l, 1)
#define XRETVAL_STRING(s) RETVAL_STRING(s, 1)
#endif /* PHP 5.x */

#include "api.h"
#include "awscrt_arginfo.h"

/* Utility macros borrowed from common */
#define GLUE(x, y) x y

#define RETURN_ARG_COUNT(_1_, _2_, _3_, _4_, _5_, count, ...) count
#define EXPAND_ARGS(args) RETURN_ARG_COUNT args
#define COUNT_ARGS_MAX5(...) EXPAND_ARGS((__VA_ARGS__, 5, 4, 3, 2, 1, 0))

#define OVERLOAD_MACRO2(name, count) name##count
#define OVERLOAD_MACRO1(name, count) OVERLOAD_MACRO2(name, count)
#define OVERLOAD_MACRO(name, count) OVERLOAD_MACRO1(name, count)

#define CALL_OVERLOAD(name, ...) GLUE(OVERLOAD_MACRO(name, COUNT_ARGS_MAX5(__VA_ARGS__)), (__VA_ARGS__))

#define VARIABLE_LENGTH_ARRAY(type, name, length) type *name = alloca(sizeof(type) * (length))

/*
 * PHP utility APIs for this extension
 */
/*
 * Exception throwing mechanism, will never return
 */
#define aws_php_throw_exception(...) CALL_OVERLOAD(_AWS_PHP_THROW_EXCEPTION, __VA_ARGS__);
#define _AWS_PHP_THROW_EXCEPTION5(format, ...) zend_error_noreturn(E_ERROR, format, __VA_ARGS__)
#define _AWS_PHP_THROW_EXCEPTION4(format, ...) zend_error_noreturn(E_ERROR, format, __VA_ARGS__)
#define _AWS_PHP_THROW_EXCEPTION3(format, ...) zend_error_noreturn(E_ERROR, format, __VA_ARGS__)
#define _AWS_PHP_THROW_EXCEPTION2(format, ...) zend_error_noreturn(E_ERROR, format, __VA_ARGS__)
#define _AWS_PHP_THROW_EXCEPTION1(format) zend_error_noreturn(E_ERROR, format)

/**
 * throws an exception resulting from argument parsing, notes the current function name in the exception
 */
#define aws_php_argparse_fail()                                                                                        \
    do {                                                                                                               \
        aws_php_throw_exception("Failed to parse arguments to %s", __func__);                                          \
    } while (0)

/**
 * calls zend_parse_parameters() with the arguments and throws an exception if parsing fails
 */
#define aws_php_parse_parameters(type_spec, ...)                                                                       \
    do {                                                                                                               \
        if (zend_parse_parameters(ZEND_NUM_ARGS(), type_spec, __VA_ARGS__) == FAILURE) {                               \
            aws_php_argparse_fail();                                                                                   \
        }                                                                                                              \
    } while (0)

/**
 * calls zend_parse_parameters_none() and throws an exception if parsing fails
 */
#define aws_php_parse_parameters_none()                                                                                \
    do {                                                                                                               \
        if (zend_parse_parameters_none() == FAILURE) {                                                                 \
            aws_php_argparse_fail();                                                                                   \
        }                                                                                                              \
    } while (0)

/* PHP/Zend utility functions to work across PHP versions */
zval *aws_php_zval_new(void);
void aws_php_zval_dtor(void *zval_ptr);
bool aws_php_zval_as_bool(zval *z);
void aws_php_zval_copy(zval *dest, zval *src);
/**
 * Replacement for ZVAL_STRINGL that is PHP version agnostic
 */
void aws_php_zval_stringl(zval *val, const char *str, size_t len);

/* Thread queue functions for managing PHP's optional threading situation */
typedef struct _aws_php_task {
    void (*callback)(void *); /* task function */
    void (*dtor)(void *);     /* deletes task_data, if non-null */
    void *data;
} aws_php_task;

/* maximum number of queued callbacks to execute at once. Since this is to support single-threaded usage,
 * this can be a fairly small number, as how many callbacks could we reasonably be stacking up?! */
#define AWS_PHP_THREAD_QUEUE_MAX_DEPTH 32

typedef struct _aws_php_thread_queue {
    struct aws_mutex mutex;
    aws_php_task queue[AWS_PHP_THREAD_QUEUE_MAX_DEPTH];
    size_t write_slot;
    aws_thread_id_t thread_id;
} aws_php_thread_queue;

extern aws_php_thread_queue s_aws_php_main_thread_queue;
bool aws_php_is_main_thread(void);

void aws_php_thread_queue_init(aws_php_thread_queue *queue);
void aws_php_thread_queue_clean_up(aws_php_thread_queue *queue);
void aws_php_thread_queue_push(aws_php_thread_queue *queue, aws_php_task task);
bool aws_php_thread_queue_drain(aws_php_thread_queue *queue);

/* called from worker thread to wait for the main thread to execute any queued work in PHP */
void aws_php_thread_queue_yield(aws_php_thread_queue *queue);

/* called from PHP thread to wait on async queued jobs, one of which MUST complete the promise */
void aws_php_thread_queue_wait(aws_php_thread_queue *queue, struct aws_promise *promise);

/**
 * generic dispatch mechanism to call a callback provided as a zval with arguments
 * that are converted to zvals based on the arg_types format string
 * Uses the same format string as zend_parse_parameters
 */
zval aws_php_invoke_callback(zval *callback, const char *arg_types, ...);

#endif /* PHP_AWS_CRT_H */