1 : // Copyright 2012 Google Inc. All Rights Reserved.
2 : //
3 : // Licensed under the Apache License, Version 2.0 (the "License");
4 : // you may not use this file except in compliance with the License.
5 : // You may obtain a copy of the License at
6 : //
7 : // http://www.apache.org/licenses/LICENSE-2.0
8 : //
9 : // Unless required by applicable law or agreed to in writing, software
10 : // distributed under the License is distributed on an "AS IS" BASIS,
11 : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 : // See the License for the specific language governing permissions and
13 : // limitations under the License.
14 : //
15 : // Defines the ThreadStateBase and ThreadStateManager classes, which assists in
16 : // tracking and properly scavenging thread local resources owned by an agent
17 : // DLL as threads attach and detach from instrumented modules.
18 :
19 : #ifndef SYZYGY_AGENT_COMMON_THREAD_STATE_H_
20 : #define SYZYGY_AGENT_COMMON_THREAD_STATE_H_
21 :
22 : #include "base/synchronization/lock.h"
23 : #include "base/win/scoped_handle.h"
24 : #include "syzygy/agent/common/dlist.h"
25 :
26 m : namespace agent {
27 m : namespace common {
28 :
29 : // An abstract base class from which agent specific thread state objects
30 : // should be derived. This object maintains a handle to the thread on which
31 : // it was created. It is therefore expected that the thread state object will
32 : // be created by the thread on which it will be used.
33 m : class ThreadStateBase {
34 m : public:
35 : // Initialize a ThreadStateBase instance.
36 m : ThreadStateBase();
37 :
38 : // A virtual destructor to allow sub-classes to be safely deleted by the
39 : // ThreadStateManager.
40 m : virtual ~ThreadStateBase() = 0;
41 :
42 m : protected:
43 m : friend class ThreadStateManager;
44 :
45 : // The handle of the owning thread, used to scavenge thread data.
46 m : base::win::ScopedHandle thread_handle_;
47 :
48 : // The entry linking us into the manager's active_items_ or death_row_ lists.
49 m : LIST_ENTRY entry_;
50 :
51 m : private:
52 m : DISALLOW_COPY_AND_ASSIGN(ThreadStateBase);
53 m : };
54 :
55 : // A thread-safe class to manage the thread local state used by an agent.
56 m : class ThreadStateManager {
57 m : public:
58 : // Initialize a ThreadStateManager instance.
59 m : ThreadStateManager();
60 :
61 : // Destroys a ThreadStateManager instance.
62 m : ~ThreadStateManager();
63 :
64 : // Insert @p item into the list of active items.
65 m : void Register(ThreadStateBase* item);
66 :
67 : // Forcibly removes a thread state @p item from the active or death-row list,
68 : // as appropriate.
69 m : void Unregister(ThreadStateBase* item);
70 :
71 : // Transfer @p item from the list of active items to the death row list. This
72 : // does not delete @p item immediately.
73 m : void MarkForDeath(ThreadStateBase* item);
74 :
75 m : protected:
76 : // A helper method which gathers up any dead items from the death row list,
77 : // optionally transfers @p item from the list of active items to the death
78 : // row list, then delete all of the dead items. As a convenience, it takes
79 : // an optional bool param which will be set to true if there are any items
80 : // still being managed by this ThreadStateManager instance upon this
81 : // functions return.
82 m : void Scavenge(ThreadStateBase* item, bool* has_items_remaining);
83 :
84 : // Gathers all items which have been marked for death whose owning threads
85 : // have terminated into @p dead_items. These items can subsequently be deleted
86 : // using the Delete() method.
87 m : void GatherDeadItemsUnlocked(LIST_ENTRY* dead_items);
88 :
89 : // Deletes (using the delete operator) each item in @p dead_items.
90 m : static void DeleteDeadItems(LIST_ENTRY* dead_items);
91 :
92 : // Returns true if the thread which owns @p item has terminated.
93 m : static bool IsThreadDead(ThreadStateBase* item);
94 :
95 : // A lock protecting access to the lists of active and death_row entries.
96 m : base::Lock lock_;
97 :
98 : // A doubly-linked list of all thread local data items not yet marked for
99 : // death. Accessed under lock_.
100 m : LIST_ENTRY active_items_;
101 :
102 : // A doubly-linked list of all thread local data items currently marked for
103 : // death. Accessed under lock_.
104 m : LIST_ENTRY death_row_items_;
105 :
106 m : private:
107 m : DISALLOW_COPY_AND_ASSIGN(ThreadStateManager);
108 m : };
109 :
110 m : } // namespace common
111 m : } // namespace agent
112 :
113 : #endif // SYZYGY_AGENT_COMMON_THREAD_STATE_H_
|