Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

php 8.4 support #515

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 36 additions & 32 deletions zend/module.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,15 @@
* from an ~user directory to be able to make changes to the globalle running
* apache process, and for example make changes to catch data from other websites
* running on the same host.
*
* However, people who are in a position to write C++ and deploy code however,
*
* However, people who are in a position to write C++ and deploy code however,
* already _ARE_ in a position to do dangerous things. For them we do not want
* these safety checks. In fact, we want to offer raw access, so that they can
* open modules - no matter what. So we had to make our own copy of the dl()
* function, and because we're here in C++ context, we do it a little nicer
* than the original C++ code. This module class is a utility class used by
* our own dl() implementation.
*
*
* @author Emiel Bruijntjes <[email protected]>
* @copyright 2015 Copernica BV
*/
Expand All @@ -25,7 +25,7 @@
* Set up namespace
*/
namespace Php {

/**
* Class definition
*/
Expand All @@ -37,13 +37,13 @@ class Module
* @var void*
*/
void *_handle;

/**
* The module entry
* @var zend_module_entry
*/
zend_module_entry *_entry = nullptr;


/**
* Internal helper class with persistent modules
Expand All @@ -56,32 +56,32 @@ class Module
* @var std::set
*/
std::set<void*> _handles;

public:
/**
* Constructor
*/
Persistent() {}

/**
* Destructor
*/
virtual ~Persistent()
virtual ~Persistent()
{
// remove all handles
while (!_handles.empty())
{
// get first handle
auto iter = _handles.begin();

// remove the handle
DL_UNLOAD(*iter);

// remove from set
_handles.erase(iter);
}
}

/**
* Check whether a handle is already persistently opened
* @param handle
Expand All @@ -91,7 +91,7 @@ class Module
{
return _handles.find(handle) != _handles.end();
}

/**
* Add a library persistently
* @param module
Expand All @@ -112,39 +112,39 @@ class Module
public:
/**
* Constructor
*
*
* A module can be loaded persistently. This means that the variables in
* the module will keep in scope for as long as Apache runs, even though
* the extension is not active in other page views
*
*
* @param module Name of the module
* @param persistent Should it be loaded persistently
*/
Module(const char *module, bool persistent)
{
// the path we're going to load
ExtensionPath path(module);

// load the module
_handle = DL_LOAD(path);

// handle should be valid
if (!_handle) return;

// if we have to open it persistently, we open it for a second time so that
// the refcounter always stays 1 or higher
if (persistent && !_persistent.contains(_handle)) _persistent.add(module);

// we have to call the get_module() function
Symbol<zend_module_entry*()> get_module(_handle, "get_module");

// was the get_module() function found
if (!get_module) return;

// retrieve the module entry
_entry = get_module();
}

/**
* Destructor
*/
Expand All @@ -153,7 +153,7 @@ class Module
// if the handle is still valid, we have to unload it
if (_handle) DL_UNLOAD((DL_HANDLE)_handle);
}

/**
* Check if the module is valid
* @return bool
Expand All @@ -162,14 +162,14 @@ class Module
{
// module-entry must exist
if (!_handle || !_entry) return false;

// check api compatibility
if (_entry->zend_api != ZEND_MODULE_API_NO) return false;

// and other stuff
return strcmp(_entry->build_id, ZEND_MODULE_BUILD_ID) == 0;
}

/**
* Start the module
* @return bool
Expand All @@ -178,22 +178,26 @@ class Module
{
// this is not possible if the module is invalid in the first place
if (!valid()) return false;

// the Zend engine sets a number of properties in the entry class, we do that here too
// note that it would be better to call zend_next_free_module() to find the next module
// number, but some users complain that this function is not always available
_entry->type = MODULE_TEMPORARY;
_entry->module_number = zend_hash_num_elements(&module_registry) + 1;
_entry->handle = _handle;

// @todo does loading an extension even work in a multi-threading setup?

// register the module, this apparently returns a copied entry pointer
#if PHP_VERSION_ID < 80400
auto *entry = zend_register_module_ex(_entry);
#else
auto *entry = zend_register_module_ex(_entry, MODULE_PERSISTENT);
#endif

// forget the entry, so that a new call to start() will fail too
_entry = nullptr;

// leap out on failure
if (entry == NULL) return false;

Expand All @@ -206,18 +210,18 @@ class Module
// call the startup function
if (entry->request_startup_func(MODULE_TEMPORARY, entry->module_number) == FAILURE) return false;
}

// all is ok, we can forget about the handle now, so that is won't get destructed
_handle = nullptr;

// enable full-table-cleanup, because inside the Zend-engine this is done too
EG(full_tables_cleanup) = 1;

// we're ready
return true;
}
};

/**
* End of namespace
*/
Expand Down