2 +----------------------------------------------------------------------+
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010-present Facebook, Inc. (http://www.facebook.com) |
6 +----------------------------------------------------------------------+
7 | This source file is subject to version 3.01 of the PHP license, |
8 | that is bundled with this package in the file LICENSE, and is |
9 | available through the world-wide-web at the following url: |
10 | http://www.php.net/license/3_01.txt |
11 | If you did not receive a copy of the PHP license and are unable to |
12 | obtain it through the world-wide-web, please send a note to |
13 | license@php.net so we can mail you a copy immediately. |
14 +----------------------------------------------------------------------+
17 #ifndef incl_HPHP_SWEEPABLE_H_
18 #define incl_HPHP_SWEEPABLE_H_
20 #include "hphp/util/assertions.h"
21 #include "hphp/util/type-scan.h"
24 ///////////////////////////////////////////////////////////////////////////////
27 * Objects that need to do special clean up at the end of the request
28 * may register themselves for this by deriving from Sweepable. After
29 * every request, MemoryManager::sweep() called each Sweepable::sweep()
30 * method, allowing objects to clean up resources that are not othewise
31 * owned by the current request, for example malloc'd-memory or file handles.
34 Sweepable(const Sweepable
&) = delete;
35 Sweepable
& operator=(const Sweepable
&) = delete;
38 * There is no default behavior. Make sure this function frees all
39 * only non-request-allocated resources.
41 virtual void sweep() = 0;
42 virtual void* owner() = 0; // return ptr to object
45 * Remove this object from the sweepable list, so it won't have
46 * sweep() called at the next SweepAll.
50 init(); // in case destructor runs later.
54 * List manipulation methods; mainly for use by MemoryManager.
57 assertx((this == m_prev
) == (this == m_next
)); // both==this or both!=this
58 return this == m_next
;
60 void init() { m_prev
= m_next
= this; }
61 Sweepable
* next() const { return m_next
; }
64 auto n
= m_next
, p
= m_prev
;
69 void enlist(Sweepable
* head
) {
70 auto next
= head
->m_next
;
73 head
->m_next
= next
->m_prev
= this;
79 explicit Sweepable(Init
) { init(); }
80 virtual ~Sweepable() { delist(); }
83 Sweepable
*m_next
, *m_prev
;
87 * SweepableMember is a Sweepable used as a member of an otherwise nonvirtual
88 * class. The member must be named m_sweepable. If T is a derived class, it
89 * should only have one m_sweepable member. Anything fancier than that voids
93 struct SweepableMember
: Sweepable
{
94 void sweep() override
{
95 auto obj
= reinterpret_cast<T
*>(
96 uintptr_t(this) - offsetof(T
, m_sweepable
)
100 void* owner() override
{
101 return reinterpret_cast<T
*>(
102 uintptr_t(this) - offsetof(T
, m_sweepable
)
107 ///////////////////////////////////////////////////////////////////////////////