ia64/xen-unstable

view extras/mini-os/events.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 06d84bf87159
children 198828cc103b
line source
1 /* -*- Mode:C; c-basic-offset:4; tab-width:4 -*-
2 ****************************************************************************
3 * (C) 2003 - Rolf Neugebauer - Intel Research Cambridge
4 * (C) 2005 - Grzegorz Milos - Intel Research Cambridge
5 ****************************************************************************
6 *
7 * File: events.c
8 * Author: Rolf Neugebauer (neugebar@dcs.gla.ac.uk)
9 * Changes: Grzegorz Milos (gm281@cam.ac.uk)
10 *
11 * Date: Jul 2003, changes Jun 2005
12 *
13 * Environment: Xen Minimal OS
14 * Description: Deals with events recieved on event channels
15 *
16 ****************************************************************************
17 */
19 #include <os.h>
20 #include <mm.h>
21 #include <hypervisor.h>
22 #include <events.h>
23 #include <lib.h>
25 static ev_action_t ev_actions[NR_EVS];
26 void default_handler(int port, struct pt_regs *regs);
29 /*
30 * Demux events to different handlers.
31 */
32 int do_event(u32 port, struct pt_regs *regs)
33 {
34 ev_action_t *action;
35 if (port >= NR_EVS) {
36 printk("Port number too large: %d\n", port);
37 return 0;
38 }
40 action = &ev_actions[port];
41 action->count++;
43 if (!action->handler)
44 goto out;
46 if (action->status & EVS_DISABLED)
47 goto out;
49 /* call the handler */
50 action->handler(port, regs);
52 clear_evtchn(port);
54 out:
55 return 1;
57 }
59 void bind_evtchn( u32 port, void (*handler)(int, struct pt_regs *) )
60 {
61 if(ev_actions[port].handler)
62 printk("WARN: Handler for port %d already registered, replacing\n",
63 port);
65 ev_actions[port].handler = handler;
66 ev_actions[port].status &= ~EVS_DISABLED;
68 /* Finally unmask the port */
69 unmask_evtchn(port);
70 }
72 int bind_virq( u32 virq, void (*handler)(int, struct pt_regs *) )
73 {
74 evtchn_op_t op;
75 int ret = 0;
77 /* Try to bind the virq to a port */
78 op.cmd = EVTCHNOP_bind_virq;
79 op.u.bind_virq.virq = virq;
81 if ( HYPERVISOR_event_channel_op(&op) != 0 )
82 {
83 ret = 1;
84 printk("Failed to bind virtual IRQ %d\n", virq);
85 goto out;
86 }
87 bind_evtchn(op.u.bind_virq.port, handler);
88 out:
89 return ret;
90 }
94 /*
95 * Initially all events are without a handler and disabled
96 */
97 void init_events(void)
98 {
99 int i;
101 /* inintialise event handler */
102 for ( i = 0; i < NR_EVS; i++ )
103 {
104 ev_actions[i].status = EVS_DISABLED;
105 ev_actions[i].handler = default_handler;
106 }
107 }
109 void default_handler(int port, struct pt_regs *regs) {
110 printk("[Port %d] - event received\n", port);
111 }