summaryrefslogtreecommitdiff
path: root/src/inc/ipcfunccall.h
blob: a29d89f6337254d09fac40742b14123bdc5e19e5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
//
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
//*****************************************************************************
// File: IPCFuncCall.h
//
// Define class to support a cross process function call. 
//
//*****************************************************************************


#ifndef _IPCFUNCCALLIMPL_H_
#define _IPCFUNCCALLIMPL_H_

//-----------------------------------------------------------------------------
// 1. Handler creates a IPCFuncCallHandler object and inits it with
// a callback function.
// 2. Source calls IPCFuncCallSource::DoThreadSafeCall(). This will pause the
// thread and trigger the callback on the handlers side.
// 
// This mechanism is very robust. See the error return codes on 
// DoThreadSafeCall() for more details.
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
// Send the call
//-----------------------------------------------------------------------------
class IPCFuncCallSource
{
public:
//.............................................................................
// Error return codes for members.
// Our biggest error concerns are timeouts and no handlers. HRESULTS won't
// help us with these, so we'll have to use our own codes.
//.............................................................................
	enum EError
	{
	// (Common) the function was called, and we waited for the full duration.
		Ok,

	// (Common) The function MAY have been called, but we timed out before it 
	// finished This means either: The function was called, but took too long 
	// to finish or The handler died on us right after we hooked up to it and 
	// so the function never even got called.
		Fail_Timeout_Call,

	// (Common) There was no handler for us to call
		Fail_NoHandler,

	// (rare) The function was never called. We successfully connected to the handler,
	// but we timed out waiting for the mutex.
		Fail_Timeout_Lock,	
			
	// (very rare) We were unable to create the mutex to serialize
		Fail_CreateMutex,

	// (very rare) Catch-all General Failure. 
		Failed
		
	};


// Make a call, wrapped in a mutex
	static EError DoThreadSafeCall();


protected:
	
};


//-----------------------------------------------------------------------------
// AuxThread Callback
//-----------------------------------------------------------------------------
DWORD WINAPI HandlerAuxThreadProc(LPVOID lpParameter);


//-----------------------------------------------------------------------------
// Callback for handler. AuxThread will call this.
//-----------------------------------------------------------------------------
typedef void (*HANDLER_CALLBACK)();

//-----------------------------------------------------------------------------
// Receieves the call. This should be in a different process than the source
//-----------------------------------------------------------------------------
class IPCFuncCallHandler
{
public:
    HRESULT InitFCHandler(HANDLER_CALLBACK pfnCallback, HANDLER_CALLBACK pfnCleanupCallback);
    void TerminateFCHandler();
    void WaitForShutdown();

    IPCFuncCallHandler();
    ~IPCFuncCallHandler();

protected:
    BOOL IsShutdownComplete();
    void SafeCleanup();
    HANDLE m_hStartEnum;	// event to notify start call
    HANDLE m_hDoneEnum;		// event to notify end call

    Volatile<HANDLE> m_hAuxThread;	// thread to listen for m_hStartEnum

    HANDLER_CALLBACK m_pfnCallback;
    HANDLER_CALLBACK m_pfnCleanupCallback;
    
    Volatile<BOOL> m_fShutdownAuxThread; // flag the Aux thread to finish up gracefully
    HANDLE m_hShutdownThread; // Event to signal the Aux thread to finish up gracefully

    HMODULE m_hCallbackModule; // Hold the module's ref to make sure that the
                               // aux thread's code doesn't get unmapped.
// Make auxthread our friend so he can access all our eventing objects
	friend DWORD WINAPI HandlerAuxThreadProc(LPVOID);
};


#endif // _IPCFUNCCALLIMPL_H_