mirror of
https://github.com/awslabs/aws-crt-php.git
synced 2026-08-17 17:47:12 +00:00
* Updated to get latest aws-crt-ffi * Added implementation for signing_result * Added main thread queue and callback queueing to signing process * Updated to get support for date on signing_config_aws * added date support to SigningConfigAWS, fixed up reference issues on http message signing * Broke C code into separate files, moved common stuff to php_aws_crt.h * Use a unity build to make PHP do the right thing with our lib * Updated aws-crt-ffi to v0.1.3 to get sigv4 changes * Added CRT::isAvailable for safe runtime detection of CRT * Fixed up test resource safety, added tests to prove it * Added CI jobs for every version of PHP on linux (#26)
167 lines
7.5 KiB
C
167 lines
7.5 KiB
C
|
|
#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)
|
|
#else /* PHP 5.5-5.6, 7.0-7.1 */
|
|
/* PHP 7.2+ always duplicate string return values */
|
|
# undef RETURN_STRING
|
|
# define RETURN_STRING(s) \
|
|
{ \
|
|
RETVAL_STRING(s, 1); \
|
|
return; \
|
|
}
|
|
# undef RETURN_STRINGL
|
|
# define RETURN_STRINGL(s, l) \
|
|
{ \
|
|
RETVAL_STRINGL(s, l, 1); \
|
|
return; \
|
|
}
|
|
# define AWS_PHP_STREAM_FROM_ZVAL(s, z) php_stream_from_zval(s, &z)
|
|
#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)
|
|
|
|
/* 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 */
|