MCPcopy Index your code
hub / github.com/rabbitstack/fibratus / GetHandleWithTimeout

Function GetHandleWithTimeout

pkg/handle/timeout.go:60–111  ·  view source on GitHub ↗

GetHandleWithTimeout is in charge of resolving handle names on handle instances that are under the risk of producing a deadlock, and thus hanging the caller thread. To prevent this kind of unwanted scenarios, deadlock aware timeout calls into `NtQueryObject` in a separate native thread. The thread i

(handle windows.Handle, timeout uint32)

Source from the content-addressed store, hash-verified

58// If the query thread doesn't notify the main thread after a prudent timeout, then the query thread is killed.
59// Subsequent calls for handle name resolution will recreate the thread in case of it not being alive.
60func GetHandleWithTimeout(handle windows.Handle, timeout uint32) (string, error) {
61 if tmt.thread == 0 {
62 if err := windows.ResetEvent(tmt.ini); err != nil {
63 return "", fmt.Errorf("couldn't reset init event: %v", err)
64 }
65 if err := windows.ResetEvent(tmt.done); err != nil {
66 return "", fmt.Errorf("couldn't reset done event: %v", err)
67 }
68 tmt.in = make(chan windows.Handle, 1)
69 tmt.out = make(chan string, 1)
70 tmt.thread = sys.CreateThread(
71 nil,
72 0,
73 windows.NewCallback(timeoutFn),
74 0,
75 0,
76 nil)
77 if tmt.thread == 0 {
78 return "", fmt.Errorf("cannot create handle query thread: %v", windows.GetLastError())
79 }
80 }
81
82 tmt.in <- handle
83 if err := windows.SetEvent(tmt.ini); err != nil {
84 return "", err
85 }
86
87 evt, err := windows.WaitForSingleObject(tmt.done, timeout)
88 if err != nil || evt == windows.WAIT_FAILED {
89 // consume pushed handle
90 <-tmt.in
91 return "", nil
92 }
93 if evt == windows.WAIT_OBJECT_0 {
94 return <-tmt.out, nil
95 }
96 if windows.Errno(evt) == windows.WAIT_TIMEOUT {
97 waitTimeoutCounts.Add(1)
98 // kill the thread and wait for its termination to orderly cleanup resources
99 if err := sys.TerminateThread(tmt.thread, 0); err != nil {
100 return "", fmt.Errorf("unable tmt terminate timeout thread: %v", err)
101 }
102 if _, err := windows.WaitForSingleObject(tmt.thread, timeout); err != nil {
103 tmt.thread = 0
104 return "", fmt.Errorf("failed awaiting timeout thread termination: %v", err)
105 }
106 _ = windows.CloseHandle(tmt.thread)
107 tmt.thread = 0
108 return "", errors.New("couldn't resolve handle name due to timeout")
109 }
110 return "", nil
111}
112
113// CloseTimeout releases event and thread handles.
114func CloseTimeout() error {

Callers 2

QueryNameFunction · 0.85
TestTimeoutFunction · 0.85

Calls 3

CreateThreadFunction · 0.92
TerminateThreadFunction · 0.92
AddMethod · 0.65

Tested by 1

TestTimeoutFunction · 0.68