Linux Kernel
3.7.1
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
tools
virtio
virtio-trace
trace-agent-ctl.c
Go to the documentation of this file.
1
/*
2
* Controller of read/write threads for virtio-trace
3
*
4
* Copyright (C) 2012 Hitachi, Ltd.
5
* Created by Yoshihiro Yunomae <
[email protected]
>
6
* Masami Hiramatsu <
[email protected]
>
7
*
8
* Licensed under GPL version 2 only.
9
*
10
*/
11
12
#define _GNU_SOURCE
13
#include <fcntl.h>
14
#include <poll.h>
15
#include <signal.h>
16
#include <
stdio.h
>
17
#include <
stdlib.h
>
18
#include <unistd.h>
19
#include "
trace-agent.h
"
20
21
#define HOST_MSG_SIZE 256
22
#define EVENT_WAIT_MSEC 100
23
24
static
volatile
sig_atomic_t global_signal_val;
25
bool
global_sig_receive
;
/* default false */
26
bool
global_run_operation
;
/* default false*/
27
28
/* Handle SIGTERM/SIGINT/SIGQUIT to exit */
29
static
void
signal_handler(
int
sig
)
30
{
31
global_signal_val =
sig
;
32
}
33
34
int
rw_ctl_init
(
const
char
*
ctl_path
)
35
{
36
int
ctl_fd;
37
38
ctl_fd =
open
(ctl_path,
O_RDONLY
);
39
if
(ctl_fd == -1) {
40
pr_err
(
"Cannot open ctl_fd\n"
);
41
goto
error
;
42
}
43
44
return
ctl_fd;
45
46
error
:
47
exit
(EXIT_FAILURE);
48
}
49
50
static
int
wait_order(
int
ctl_fd)
51
{
52
struct
pollfd
poll_fd;
53
int
ret
= 0;
54
55
while
(!
global_sig_receive
) {
56
poll_fd.fd = ctl_fd;
57
poll_fd.events =
POLLIN
;
58
59
ret =
poll
(&poll_fd, 1,
EVENT_WAIT_MSEC
);
60
61
if
(global_signal_val) {
62
global_sig_receive
=
true
;
63
pr_info
(
"Receive interrupt %d\n"
, global_signal_val);
64
65
/* Wakes rw-threads when they are sleeping */
66
if
(!
global_run_operation
)
67
pthread_cond_broadcast(&
cond_wakeup
);
68
69
ret = -1;
70
break
;
71
}
72
73
if
(ret < 0) {
74
pr_err
(
"Polling error\n"
);
75
goto
error
;
76
}
77
78
if
(ret)
79
break
;
80
};
81
82
return
ret
;
83
84
error
:
85
exit
(EXIT_FAILURE);
86
}
87
88
/*
89
* contol read/write threads by handling global_run_operation
90
*/
91
void
*
rw_ctl_loop
(
int
ctl_fd)
92
{
93
ssize_t
rlen;
94
char
buf
[
HOST_MSG_SIZE
];
95
int
ret
;
96
97
/* Setup signal handlers */
98
signal(
SIGTERM
, signal_handler);
99
signal(
SIGINT
, signal_handler);
100
signal(
SIGQUIT
, signal_handler);
101
102
while
(!
global_sig_receive
) {
103
104
ret = wait_order(ctl_fd);
105
if
(ret < 0)
106
break
;
107
108
rlen =
read
(ctl_fd, buf,
sizeof
(buf));
109
if
(rlen < 0) {
110
pr_err
(
"read data error in ctl thread\n"
);
111
goto
error
;
112
}
113
114
if
(rlen == 2 && buf[0] ==
'1'
) {
115
/*
116
* If host writes '1' to a control path,
117
* this controller wakes all read/write threads.
118
*/
119
global_run_operation
=
true
;
120
pthread_cond_broadcast(&
cond_wakeup
);
121
pr_debug
(
"Wake up all read/write threads\n"
);
122
}
else
if
(rlen == 2 && buf[0] ==
'0'
) {
123
/*
124
* If host writes '0' to a control path, read/write
125
* threads will wait for notification from Host.
126
*/
127
global_run_operation
=
false
;
128
pr_debug
(
"Stop all read/write threads\n"
);
129
}
else
130
pr_info
(
"Invalid host notification: %s\n"
, buf);
131
}
132
133
return
NULL
;
134
135
error
:
136
exit
(EXIT_FAILURE);
137
}
Generated on Thu Jan 10 2013 15:09:34 for Linux Kernel by
1.8.2