mirror of
https://github.com/awslabs/aws-crt-php.git
synced 2026-08-18 01:57:13 +00:00
Organized modules, added indirection for FFI vs extension loading (#10)
* mv src -> ext, lib -> src to be more in line with PHP module expectations * Fixed dependency for ffi test * Fixed path in format-check to C source * CRT will now try the extension first, then FFI
This commit is contained in:
@@ -181,6 +181,7 @@ fabric.properties
|
|||||||
.libs/
|
.libs/
|
||||||
build/
|
build/
|
||||||
configure.in
|
configure.in
|
||||||
|
configure.ac
|
||||||
mkinstalldirs
|
mkinstalldirs
|
||||||
run-tests.php
|
run-tests.php
|
||||||
Makefile.global
|
Makefile.global
|
||||||
|
|||||||
+11
-7
@@ -40,16 +40,20 @@ $(BUILD_DIR)/aws-crt-ffi/CMakeCache.txt: $(INT_DIR)/lib/libcrypto.a
|
|||||||
$(BUILD_DIR)/aws-crt-ffi/libaws-crt-ffi.so: $(BUILD_DIR)/aws-crt-ffi/CMakeCache.txt
|
$(BUILD_DIR)/aws-crt-ffi/libaws-crt-ffi.so: $(BUILD_DIR)/aws-crt-ffi/CMakeCache.txt
|
||||||
$(CMAKE_BUILD) build/aws-crt-ffi $(CMAKE_TARGET)
|
$(CMAKE_BUILD) build/aws-crt-ffi $(CMAKE_TARGET)
|
||||||
|
|
||||||
# copy the lib into the lib folder
|
# copy the lib into the src folder
|
||||||
$(INSTALL_DIR)/lib/libaws-crt-ffi.so: $(BUILD_DIR)/aws-crt-ffi/libaws-crt-ffi.so $(INSTALL_DIR)/lib/api.h
|
$(INSTALL_DIR)/src/libaws-crt-ffi.so: $(BUILD_DIR)/aws-crt-ffi/libaws-crt-ffi.so $(INSTALL_DIR)/src/api.h
|
||||||
cp -v $(BUILD_DIR)/aws-crt-ffi/libaws-crt-ffi.so $(INSTALL_DIR)/lib/libaws-crt-ffi.so
|
cp -v $(BUILD_DIR)/aws-crt-ffi/libaws-crt-ffi.so $(INSTALL_DIR)/src/libaws-crt-ffi.so
|
||||||
|
|
||||||
# install api.h from FFI lib
|
# install api.h from FFI lib
|
||||||
$(INSTALL_DIR)/lib/api.h: crt/aws-crt-ffi/src/api.h
|
$(INSTALL_DIR)/src/api.h: crt/aws-crt-ffi/src/api.h
|
||||||
cat crt/aws-crt-ffi/src/api.h | grep -v AWS_EXTERN_C | sed -e 's/AWS_CRT_API //' | grep -ve '^#' > $(INSTALL_DIR)/lib/api.h
|
cat crt/aws-crt-ffi/src/api.h | grep -v AWS_EXTERN_C | sed -e 's/AWS_CRT_API //' | grep -ve '^#' > $(INSTALL_DIR)/src/api.h
|
||||||
|
|
||||||
|
# copy the FFI lib from src to ext for the extension to use
|
||||||
|
$(INSTALL_DIR)/ext/libaws-crt-ffi.so: $(INSTALL_DIR)/src/libaws-crt-ffi.so
|
||||||
|
cp -v $(INSTALL_DIR)/src/libaws-crt-ffi.so $(INSTALL_DIR)/ext/libaws-crt-ffi.so
|
||||||
|
|
||||||
# Force the crt object target to depend on the FFI library
|
# Force the crt object target to depend on the FFI library
|
||||||
src/crt.lo: $(INSTALL_DIR)/lib/libaws-crt-ffi.so
|
ext/crt.lo: $(INSTALL_DIR)/ext/libaws-crt-ffi.so
|
||||||
|
|
||||||
ifeq ($(TEST_FFI),1)
|
ifeq ($(TEST_FFI),1)
|
||||||
test-ci: test-ffi
|
test-ci: test-ffi
|
||||||
@@ -58,6 +62,6 @@ test-ci: test
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
# Test the FFI interface
|
# Test the FFI interface
|
||||||
test-ffi: $(INSTALL_DIR)/lib/libaws-crt-ffi.so
|
test-ffi: $(INSTALL_DIR)/src/libaws-crt-ffi.so
|
||||||
composer update
|
composer update
|
||||||
composer run test
|
composer run test
|
||||||
|
|||||||
+4
-7
@@ -12,19 +12,16 @@
|
|||||||
},
|
},
|
||||||
"autoload": {
|
"autoload": {
|
||||||
"classmap": [
|
"classmap": [
|
||||||
"lib/"
|
"src/"
|
||||||
],
|
]
|
||||||
"psr-4": {
|
|
||||||
"AWS\\": "lib/AWS"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"autoload-dev": {
|
"autoload-dev": {
|
||||||
"classmap": [
|
"classmap": [
|
||||||
"lib/tests/"
|
"src/tests/"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "phpunit lib/tests"
|
"test": "phpunit src/tests"
|
||||||
},
|
},
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"authors": [
|
"authors": [
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ if test "$PHP_AWSCRT" != "no"; then
|
|||||||
PHP_SUBST(AWSCRT_SHARED_LIBADD)
|
PHP_SUBST(AWSCRT_SHARED_LIBADD)
|
||||||
|
|
||||||
# Sources for the PHP extension itself
|
# Sources for the PHP extension itself
|
||||||
AWSCRT_SOURCES=src/*.c
|
AWSCRT_SOURCES=ext/*.c
|
||||||
PHP_NEW_EXTENSION(awscrt, $AWSCRT_SOURCES, $ext_shared)
|
PHP_NEW_EXTENSION(awscrt, $AWSCRT_SOURCES, $ext_shared)
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,2 @@
|
|||||||
|
*.so
|
||||||
|
api.h
|
||||||
+1
-1
@@ -10,7 +10,7 @@ if NOT type $CLANG_FORMAT 2> /dev/null ; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
FAIL=0
|
FAIL=0
|
||||||
SOURCE_FILES=`find src -type f \( -name '*.h' -o -name '*.c' \)`
|
SOURCE_FILES=`find ext -type f \( -name '*.h' -o -name '*.c' \)`
|
||||||
for i in $SOURCE_FILES
|
for i in $SOURCE_FILES
|
||||||
do
|
do
|
||||||
$CLANG_FORMAT -output-replacements-xml $i | grep -c "<replacement " > /dev/null
|
$CLANG_FORMAT -output-replacements-xml $i | grep -c "<replacement " > /dev/null
|
||||||
|
|||||||
@@ -1,21 +1,33 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
namespace AWS\CRT;
|
||||||
|
|
||||||
|
use AWS\CRT\Internal\Extension;
|
||||||
|
use AWS\CRT\Internal\FFI;
|
||||||
|
|
||||||
|
use \RuntimeException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Wrapper for the FFI interface to the CRT. There only ever needs to be one of these.
|
* Wrapper for the interface to the CRT. There only ever needs to be one of these, but
|
||||||
|
* additional instances won't cost anything other than their memory.
|
||||||
* Creating an instance of any NativeResource will activate the CRT binding. User code
|
* Creating an instance of any NativeResource will activate the CRT binding. User code
|
||||||
* should only need to create one of these if they are only accessing CRT:: functions.
|
* should only need to create one of these if they are only accessing CRT:: static functions.
|
||||||
*/
|
*/
|
||||||
final class CRT {
|
final class CRT {
|
||||||
private static $ffi = null;
|
|
||||||
|
private static $impl = null;
|
||||||
private static $refcount = 0;
|
private static $refcount = 0;
|
||||||
|
|
||||||
function __construct() {
|
function __construct() {
|
||||||
if (is_null(self::$ffi)) {
|
if (is_null(self::$impl)) {
|
||||||
try {
|
try {
|
||||||
self::$ffi = FFI::cdef(file_get_contents(__DIR__ . "/../api.h"), __DIR__ . "/../libaws-crt-ffi.so");
|
self::$impl = new Extension();
|
||||||
self::init();
|
} catch (RuntimeException $rex) {
|
||||||
} catch (Exception $e) {
|
try {
|
||||||
echo 'Exception while initializing CRT via FFI: ', $e->getMessage(), "\n";
|
self::$impl = new FFI();
|
||||||
|
} catch (RuntimeException $frex) {
|
||||||
|
throw new RuntimeException('Unable to initialize AWS CRT via extension or FFI', -1, $frex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
++self::$refcount;
|
++self::$refcount;
|
||||||
@@ -23,24 +35,15 @@ final class CRT {
|
|||||||
|
|
||||||
function __destruct() {
|
function __destruct() {
|
||||||
if (--self::$refcount == 0) {
|
if (--self::$refcount == 0) {
|
||||||
self::clean_up();
|
self::$impl = null;
|
||||||
self::$ffi = null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static function init() {
|
|
||||||
return self::$ffi->aws_crt_init();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static function clean_up() {
|
|
||||||
return self::$ffi->aws_crt_clean_up();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return integer last error code reported within the CRT
|
* @return integer last error code reported within the CRT
|
||||||
*/
|
*/
|
||||||
public static function last_error() {
|
public static function last_error() {
|
||||||
return self::$ffi->aws_crt_last_error();
|
return self::$impl->aws_crt_last_error();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -48,7 +51,7 @@ final class CRT {
|
|||||||
* @return string Human-readable description of the provided error code
|
* @return string Human-readable description of the provided error code
|
||||||
*/
|
*/
|
||||||
public static function error_str($error) {
|
public static function error_str($error) {
|
||||||
return self::$ffi->aws_crt_error_str((int) $error);
|
return self::$impl->aws_crt_error_str((int) $error);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -56,14 +59,14 @@ final class CRT {
|
|||||||
* @return string Name/enum identifier for the provided error code
|
* @return string Name/enum identifier for the provided error code
|
||||||
*/
|
*/
|
||||||
public static function error_name($error) {
|
public static function error_name($error) {
|
||||||
return self::$ffi->aws_crt_error_name((int) $error);
|
return self::$impl->aws_crt_error_name((int) $error);
|
||||||
}
|
}
|
||||||
|
|
||||||
function event_loop_group_new($num_threads) {
|
function event_loop_group_new($num_threads) {
|
||||||
return self::$ffi->aws_crt_event_loop_group_new($num_threads);
|
return self::$impl->aws_crt_event_loop_group_new($num_threads);
|
||||||
}
|
}
|
||||||
|
|
||||||
function event_loop_group_release($elg) {
|
function event_loop_group_release($elg) {
|
||||||
return self::$ffi->aws_crt_event_loop_group_release($elg);
|
return self::$impl->aws_crt_event_loop_group_release($elg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,9 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
namespace AWS\CRT\IO;
|
||||||
|
|
||||||
|
use AWS\CRT\NativeResource as NativeResource;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents 1 or more event loops (1 per thread) for doing I/O and background tasks.
|
* Represents 1 or more event loops (1 per thread) for doing I/O and background tasks.
|
||||||
* Typically, every application has one EventLoopGroup.
|
* Typically, every application has one EventLoopGroup.
|
||||||
@@ -24,8 +28,7 @@ final class EventLoopGroup extends NativeResource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function __destruct() {
|
function __destruct() {
|
||||||
self::$crt->event_loop_group_release($this->native);
|
self::$crt->event_loop_group_release($this->release());
|
||||||
$this->release();
|
|
||||||
parent::__destruct();
|
parent::__destruct();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace AWS\CRT\Internal;
|
||||||
|
|
||||||
|
use \RuntimeException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @internal
|
||||||
|
* Forwards calls on to awscrt PHP extension functions
|
||||||
|
*/
|
||||||
|
final class Extension {
|
||||||
|
function __construct() {
|
||||||
|
if (!extension_loaded('awscrt')) {
|
||||||
|
throw new RuntimeException('awscrt extension is not loaded');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Forwards any call made on this object to the extension function of the
|
||||||
|
* same name with the supplied arguments. Argument type hinting and checking
|
||||||
|
* occurs at the CRT wrapper.
|
||||||
|
*/
|
||||||
|
function __call(string $name, $args) {
|
||||||
|
return call_user_func_array($name, $args);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace AWS\CRT\Internal;
|
||||||
|
|
||||||
|
use \Exception;
|
||||||
|
use \RuntimeException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @internal
|
||||||
|
* Forwards calls on to libaws-crt-ffi via FFI
|
||||||
|
*/
|
||||||
|
final class FFI {
|
||||||
|
private static $ffi = null;
|
||||||
|
private static $refcount = 0;
|
||||||
|
|
||||||
|
function __construct() {
|
||||||
|
if (is_null(self::$ffi)) {
|
||||||
|
try {
|
||||||
|
self::$ffi = \FFI::cdef(file_get_contents(__DIR__ . "/../../../api.h"), __DIR__ . "/../../../libaws-crt-ffi.so");
|
||||||
|
self::init();
|
||||||
|
} catch (Exception $e) {
|
||||||
|
throw new RuntimeException('Exception while initializing CRT via FFI', 0, $e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
++self::$refcount;
|
||||||
|
}
|
||||||
|
|
||||||
|
function __destruct() {
|
||||||
|
if (--self::$refcount == 0) {
|
||||||
|
self::clean_up();
|
||||||
|
self::$ffi = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Forwards any call made on this object to the FFI function of the
|
||||||
|
* same name with the supplied arguments. Argument type hinting and checking
|
||||||
|
* occurs at the CRT wrapper.
|
||||||
|
*/
|
||||||
|
function __call(string $name, $args) {
|
||||||
|
return call_user_func_array(array(self::$ffi, $name), $args);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static function init() {
|
||||||
|
return self::$ffi->aws_crt_init();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static function clean_up() {
|
||||||
|
return self::$ffi->aws_crt_clean_up();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,9 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
namespace AWS\CRT;
|
||||||
|
|
||||||
|
use AWS\CRT\CRT as CRT;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base class for all native resources, tracks all outstanding resources
|
* Base class for all native resources, tracks all outstanding resources
|
||||||
* and provides basic leak checking
|
* and provides basic leak checking
|
||||||
@@ -11,11 +15,7 @@ abstract class NativeResource {
|
|||||||
|
|
||||||
function __construct() {
|
function __construct() {
|
||||||
if (is_null(self::$crt)) {
|
if (is_null(self::$crt)) {
|
||||||
try {
|
|
||||||
self::$crt = new CRT();
|
self::$crt = new CRT();
|
||||||
} catch (Exception $e) {
|
|
||||||
echo 'Exception while loading CRT: ', $e->getMessage(), "\n";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
self::$resources[spl_object_hash($this)] = 1;
|
self::$resources[spl_object_hash($this)] = 1;
|
||||||
@@ -26,7 +26,9 @@ abstract class NativeResource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected function release() {
|
protected function release() {
|
||||||
|
$native = $this->native;
|
||||||
$this->native = null;
|
$this->native = null;
|
||||||
|
return $native;
|
||||||
}
|
}
|
||||||
|
|
||||||
function __destruct() {
|
function __destruct() {
|
||||||
@@ -1,5 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
use AWS\CRT\CRT;
|
||||||
|
|
||||||
final class ErrorTest extends PHPUnit_Framework_TestCase {
|
final class ErrorTest extends PHPUnit_Framework_TestCase {
|
||||||
private static $crt = null;
|
private static $crt = null;
|
||||||
public static function setUpBeforeClass() {
|
public static function setUpBeforeClass() {
|
||||||
@@ -1,9 +1,12 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
use AWS\CRT\IO\EventLoopGroup as EventLoopGroup;
|
||||||
|
|
||||||
final class EventLoopGroupTest extends PHPUnit_Framework_TestCase {
|
final class EventLoopGroupTest extends PHPUnit_Framework_TestCase {
|
||||||
|
|
||||||
public function testLifetime() {
|
public function testLifetime() {
|
||||||
$elg = new EventLoopGroup();
|
$elg = new EventLoopGroup();
|
||||||
|
$this->assertNotNull($elg, "Failed to create default EventLoopGroup");
|
||||||
$elg = null;
|
$elg = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -11,6 +14,7 @@ final class EventLoopGroupTest extends PHPUnit_Framework_TestCase {
|
|||||||
$options = EventLoopGroup::defaults();
|
$options = EventLoopGroup::defaults();
|
||||||
$options['num_threads'] = 1;
|
$options['num_threads'] = 1;
|
||||||
$elg = new EventLoopGroup($options);
|
$elg = new EventLoopGroup($options);
|
||||||
|
$this->assertNotNull($elg, "Failed to create EventLoopGroup with 1 thread");
|
||||||
$elg = null;
|
$elg = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user