ia64/xen-unstable

view tools/libxc/xc_evtchn.c @ 7238:971e7c7411b3

Raise an exception if an error appears on the pipes to our children, and make
sure that the child's pipes are closed even under that exception. Move the
handling of POLLHUP to the end of the loop, so that we guarantee to read any
remaining data from the child if POLLHUP and POLLIN appear at the same time.

Signed-off-by: Ewan Mellor <ewan@xensource.com>
author emellor@ewan
date Thu Oct 06 10:13:11 2005 +0100 (2005-10-06)
parents ec84b119e4ed
children c3d9b7013b14
line source
1 /******************************************************************************
2 * xc_evtchn.c
3 *
4 * API for manipulating and accessing inter-domain event channels.
5 *
6 * Copyright (c) 2004, K A Fraser.
7 */
9 #include "xc_private.h"
12 static int do_evtchn_op(int xc_handle, evtchn_op_t *op)
13 {
14 int ret = -1;
15 privcmd_hypercall_t hypercall;
17 hypercall.op = __HYPERVISOR_event_channel_op;
18 hypercall.arg[0] = (unsigned long)op;
20 if ( mlock(op, sizeof(*op)) != 0 )
21 {
22 PERROR("do_evtchn_op: op mlock failed");
23 goto out;
24 }
26 if ((ret = do_xen_hypercall(xc_handle, &hypercall)) < 0)
27 ERROR("do_evtchn_op: HYPERVISOR_event_channel_op failed: %d", ret);
29 safe_munlock(op, sizeof(*op));
30 out:
31 return ret;
32 }
35 int xc_evtchn_alloc_unbound(int xc_handle,
36 u32 dom,
37 int *port)
38 {
39 evtchn_op_t op;
40 int rc;
42 op.cmd = EVTCHNOP_alloc_unbound;
43 op.u.alloc_unbound.dom = (domid_t)dom;
44 op.u.alloc_unbound.port = (port != NULL) ? *port : 0;
46 if ( (rc = do_evtchn_op(xc_handle, &op)) == 0 )
47 {
48 if ( port != NULL )
49 *port = op.u.alloc_unbound.port;
50 }
52 return rc;
53 }
56 int xc_evtchn_bind_interdomain(int xc_handle,
57 u32 dom1,
58 u32 dom2,
59 int *port1,
60 int *port2)
61 {
62 evtchn_op_t op;
63 int rc;
65 op.cmd = EVTCHNOP_bind_interdomain;
66 op.u.bind_interdomain.dom1 = (domid_t)dom1;
67 op.u.bind_interdomain.dom2 = (domid_t)dom2;
68 op.u.bind_interdomain.port1 = (port1 != NULL) ? *port1 : 0;
69 op.u.bind_interdomain.port2 = (port2 != NULL) ? *port2 : 0;
72 if ( (rc = do_evtchn_op(xc_handle, &op)) == 0 )
73 {
74 if ( port1 != NULL )
75 *port1 = op.u.bind_interdomain.port1;
76 if ( port2 != NULL )
77 *port2 = op.u.bind_interdomain.port2;
78 }
80 return rc;
81 }
84 int xc_evtchn_bind_virq(int xc_handle,
85 int virq,
86 int *port)
87 {
88 evtchn_op_t op;
89 int rc;
91 op.cmd = EVTCHNOP_bind_virq;
92 op.u.bind_virq.virq = (u32)virq;
93 op.u.bind_virq.vcpu = 0;
95 if ( (rc = do_evtchn_op(xc_handle, &op)) == 0 )
96 {
97 if ( port != NULL )
98 *port = op.u.bind_virq.port;
99 }
101 return rc;
102 }
105 int xc_evtchn_close(int xc_handle,
106 u32 dom,
107 int port)
108 {
109 evtchn_op_t op;
110 op.cmd = EVTCHNOP_close;
111 op.u.close.dom = (domid_t)dom;
112 op.u.close.port = port;
113 return do_evtchn_op(xc_handle, &op);
114 }
117 int xc_evtchn_send(int xc_handle,
118 int local_port)
119 {
120 evtchn_op_t op;
121 op.cmd = EVTCHNOP_send;
122 op.u.send.local_port = local_port;
123 return do_evtchn_op(xc_handle, &op);
124 }
127 int xc_evtchn_status(int xc_handle,
128 u32 dom,
129 int port,
130 xc_evtchn_status_t *status)
131 {
132 evtchn_op_t op;
133 int rc;
135 op.cmd = EVTCHNOP_status;
136 op.u.status.dom = (domid_t)dom;
137 op.u.status.port = port;
139 if ( (rc = do_evtchn_op(xc_handle, &op)) == 0 )
140 memcpy(status, &op.u.status, sizeof(*status));
142 return rc;
143 }