Provide safe storage for private PHP data in external thread events
Sometimes, a PHP object (usually defined by extension) is needed to unserialize the data. Provide a safe mechanism to store such object with external thread events.
Esse commit está contido em:
@@ -23,10 +23,10 @@
|
||||
namespace HPHP {
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AsioExternalThreadEvent::AsioExternalThreadEvent()
|
||||
AsioExternalThreadEvent::AsioExternalThreadEvent(ObjectData* priv_data)
|
||||
: m_session(AsioSession::Get()),
|
||||
m_state(Waiting) {
|
||||
m_waitHandle = c_ExternalThreadEventWaitHandle::Create(this);
|
||||
m_waitHandle = c_ExternalThreadEventWaitHandle::Create(this, priv_data);
|
||||
}
|
||||
|
||||
void AsioExternalThreadEvent::abandon() {
|
||||
|
||||
@@ -195,7 +195,15 @@ class AsioExternalThreadEvent {
|
||||
virtual void unserialize(TypedValue* result) const = 0;
|
||||
|
||||
protected:
|
||||
AsioExternalThreadEvent();
|
||||
/**
|
||||
* Construct AsioExternalThreadEvent
|
||||
*
|
||||
* Subclass may optionally pass a PHP object (usually defined by extension)
|
||||
* that can be accessed during unserialize() via getPrivData(). A reference
|
||||
* to the object will be held while associated ExternalThreadEventWaitHandle
|
||||
* object is in WAITING state.
|
||||
*/
|
||||
explicit AsioExternalThreadEvent(ObjectData* priv_data = nullptr);
|
||||
|
||||
/**
|
||||
* Destruct AsioExternalThreadEvent
|
||||
@@ -222,6 +230,17 @@ class AsioExternalThreadEvent {
|
||||
*/
|
||||
void markAsFinished();
|
||||
|
||||
/**
|
||||
* Get private PHP data needed for unserialization.
|
||||
*
|
||||
* This function obtains private data stored by constructor. It may be
|
||||
* called only from the unserialize() implementation.
|
||||
*/
|
||||
ObjectData* getPrivData() const {
|
||||
assert(m_state.load() == Finished);
|
||||
return m_waitHandle->getPrivData();
|
||||
}
|
||||
|
||||
private:
|
||||
enum state_t : uint32_t {
|
||||
/**
|
||||
|
||||
@@ -62,16 +62,17 @@ void c_ExternalThreadEventWaitHandle::t___construct() {
|
||||
throw e;
|
||||
}
|
||||
|
||||
c_ExternalThreadEventWaitHandle* c_ExternalThreadEventWaitHandle::Create(AsioExternalThreadEvent* event) {
|
||||
c_ExternalThreadEventWaitHandle* c_ExternalThreadEventWaitHandle::Create(AsioExternalThreadEvent* event, ObjectData* priv_data) {
|
||||
c_ExternalThreadEventWaitHandle* wh = NEWOBJ(c_ExternalThreadEventWaitHandle);
|
||||
wh->initialize(event);
|
||||
wh->initialize(event, priv_data);
|
||||
return wh;
|
||||
}
|
||||
|
||||
void c_ExternalThreadEventWaitHandle::initialize(AsioExternalThreadEvent* event) {
|
||||
void c_ExternalThreadEventWaitHandle::initialize(AsioExternalThreadEvent* event, ObjectData* priv_data) {
|
||||
// this wait handle is owned by existence of unprocessed event
|
||||
incRefCount();
|
||||
m_event = event;
|
||||
m_privData = priv_data;
|
||||
|
||||
setState(STATE_WAITING);
|
||||
if (isInContext()) {
|
||||
@@ -114,6 +115,7 @@ void c_ExternalThreadEventWaitHandle::process() {
|
||||
// event is processed, destroy it, unregister sweepable and decref ownership
|
||||
m_event->release();
|
||||
m_event = nullptr;
|
||||
m_privData = nullptr;
|
||||
unregister();
|
||||
decRefObj(this);
|
||||
}
|
||||
|
||||
@@ -439,10 +439,11 @@ class c_ExternalThreadEventWaitHandle : public c_WaitableWaitHandle, public Swee
|
||||
public: void t___construct();
|
||||
|
||||
public:
|
||||
static c_ExternalThreadEventWaitHandle* Create(AsioExternalThreadEvent* event);
|
||||
static c_ExternalThreadEventWaitHandle* Create(AsioExternalThreadEvent* event, ObjectData* priv_data);
|
||||
|
||||
c_ExternalThreadEventWaitHandle* getNextToProcess() { assert(getState() == STATE_WAITING); return m_nextToProcess; }
|
||||
void setNextToProcess(c_ExternalThreadEventWaitHandle* next) { assert(getState() == STATE_WAITING); m_nextToProcess = next; }
|
||||
ObjectData* getPrivData() { return m_privData.get(); }
|
||||
void setIndex(uint32_t ete_idx) { assert(getState() == STATE_WAITING); m_index = ete_idx; }
|
||||
|
||||
void abandon(bool sweeping);
|
||||
@@ -452,10 +453,11 @@ class c_ExternalThreadEventWaitHandle : public c_WaitableWaitHandle, public Swee
|
||||
void exitContext(context_idx_t ctx_idx);
|
||||
|
||||
private:
|
||||
void initialize(AsioExternalThreadEvent* event);
|
||||
void initialize(AsioExternalThreadEvent* event, ObjectData* priv_data);
|
||||
|
||||
c_ExternalThreadEventWaitHandle* m_nextToProcess;
|
||||
AsioExternalThreadEvent* m_event;
|
||||
Object m_privData;
|
||||
uint32_t m_index;
|
||||
|
||||
static const uint8_t STATE_WAITING = 3;
|
||||
|
||||
Referência em uma Nova Issue
Bloquear um usuário