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 if it's called on @p items' own
73 : // thread.
74 m : void MarkForDeath(ThreadStateBase* item);
75 :
76 m : protected:
77 : // A helper method which gathers up any dead items from the death row list.
78 : // @returns true iff there are any items still being managed by this
79 : // ThreadStateManager instance upon this functions return.
80 m : bool Scavenge();
81 :
82 : // Gathers all items which have been marked for death whose owning threads
83 : // have terminated into @p dead_items. These items can subsequently be
84 : // deleted using the Delete() method.
85 m : void GatherDeadItemsUnlocked(LIST_ENTRY* dead_items);
86 :
87 : // Deletes (using the delete operator) each item in @p items.
88 m : static void DeleteItems(LIST_ENTRY* items);
89 :
90 : // Returns true if the thread which owns @p item has terminated.
91 m : static bool IsThreadDead(ThreadStateBase* item);
92 :
93 : // A lock protecting access to the lists of active and death_row entries.
94 m : base::Lock lock_;
95 :
96 : // A doubly-linked list of all thread local data items not yet marked for
97 : // death. Accessed under lock_.
98 m : LIST_ENTRY active_items_;
99 :
100 : // A doubly-linked list of all thread local data items currently marked for
101 : // death. Accessed under lock_.
102 m : LIST_ENTRY death_row_items_;
103 :
104 m : private:
105 m : DISALLOW_COPY_AND_ASSIGN(ThreadStateManager);
106 m : };
107 :
108 m : } // namespace common
109 m : } // namespace agent
110 :
111 : #endif // SYZYGY_AGENT_COMMON_THREAD_STATE_H_
|