blob: 3906aa24408c9e389b2f03e257210566ee6fda34 (
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
|
/*
TODO: MP AB Copyright
*/
/*
Design
- Mutex-guarded request queue (it belongs to the target), which can be enabled/
disabled (when empty).
- After the request has been put into queue, the requestor waits for request
to be satisfied. The worker satisifes the request and signals the
requestor.
*/
/*
Target for asynchronous calls.
*/
class Apc_target
{
public:
Apc_target() : enabled(0), apc_calls(NULL) /*, call_queue_size(0)*/ {}
~Apc_target() { DBUG_ASSERT(!enabled && !apc_calls);}
/*
Initialize the target. This must be called before anything else. Right
after initialization, the target is disabled.
*/
void init();
/*
Destroy the target. The target must be disabled when this call is made.
*/
void destroy();
/*
Enter into state where this target will be serving APC requests
*/
void enable();
/*
Leave the state where we could serve APC requests (will serve all already
enqueued requests)
*/
void disable();
/*
This should be called periodically to serve observation requests.
*/
void process_apc_requests();
typedef void (*apc_func_t)(void *arg);
/*
Make an APC call: schedule it for execution and wait until the target
thread has executed it. This function must not be called from a thread
that's different from the target thread.
@retval FALSE - Ok, the call has been made
@retval TRUE - Call wasnt made (either the target is in disabled state or
timeout occured)
*/
bool make_apc_call(apc_func_t func, void *func_arg,
int timeout_sec, bool *timed_out);
#ifndef DBUG_OFF
int n_calls_processed;
//int call_queue_size;
#endif
private:
class Call_request;
int enabled;
Call_request *apc_calls;
pthread_mutex_t LOCK_apc_queue;
class Call_request
{
public:
apc_func_t func;
void *func_arg;
bool done;
pthread_mutex_t LOCK_request;
pthread_cond_t COND_request;
Call_request *next;
Call_request *prev;
const char *what;
};
void enqueue_request(Call_request *qe);
void dequeue_request(Call_request *qe);
Call_request *get_first_in_queue()
{
return apc_calls;
}
};
///////////////////////////////////////////////////////////////////////
|