Pretty printing.
[kopensolaris-gnu/glibc.git] / nptl_db / td_thr_event_getmsg.c
1 /* Retrieve event.
2    Copyright (C) 1999, 2001, 2002, 2003 Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
4    Contributed by Ulrich Drepper <drepper@redhat.com>, 1999.
5
6    The GNU C Library is free software; you can redistribute it and/or
7    modify it under the terms of the GNU Lesser General Public
8    License as published by the Free Software Foundation; either
9    version 2.1 of the License, or (at your option) any later version.
10
11    The GNU C Library is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14    Lesser General Public License for more details.
15
16    You should have received a copy of the GNU Lesser General Public
17    License along with the GNU C Library; if not, write to the Free
18    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19    02111-1307 USA.  */
20
21 #include <stddef.h>
22 #include <string.h>
23
24 #include "thread_dbP.h"
25
26
27 td_err_e
28 td_thr_event_getmsg (const td_thrhandle_t *th, td_event_msg_t *msg)
29 {
30   td_eventbuf_t event;
31
32   LOG ("td_thr_event_getmsg");
33
34   /* Read the event structure from the target.  */
35   if (ps_pdread (th->th_ta_p->ph,
36                  ((char *) th->th_unique
37                   + offsetof (struct pthread, eventbuf)),
38                  &event, sizeof (td_eventbuf_t)) != PS_OK)
39     return TD_ERR;      /* XXX Other error value?  */
40
41   /* Check whether an event occurred.  */
42   if (event.eventnum == TD_EVENT_NONE)
43     /* Nothing.  */
44     return TD_NOMSG;
45
46   /* Fill the user's data structure.  */
47   msg->event = event.eventnum;
48   msg->th_p = th;
49   msg->msg.data = (uintptr_t) event.eventdata;
50
51   /* And clear the event message in the target.  */
52   memset (&event, '\0', sizeof (td_eventbuf_t));
53   if (ps_pdwrite (th->th_ta_p->ph,
54                   ((char *) th->th_unique
55                    + offsetof (struct pthread, eventbuf)),
56                   &event, sizeof (td_eventbuf_t)) != PS_OK)
57     return TD_ERR;      /* XXX Other error value?  */
58
59   /* Get the pointer to the thread descriptor with the last event.
60      If it doesn't match TH, then walk down the list until we find it.
61      We must splice it out of the list so that there is no dangling
62      pointer to it later when it dies.  */
63   psaddr_t thp, prevp = th->th_ta_p->pthread_last_event;
64   if (ps_pdread (th->th_ta_p->ph,
65                  prevp, &thp, sizeof (struct pthread *)) != PS_OK)
66     return TD_ERR;      /* XXX Other error value?  */
67
68   psaddr_t next;
69   while (thp != 0)
70     {
71       if (ps_pdread (th->th_ta_p->ph,
72                      (char *) thp + offsetof (struct pthread, nextevent),
73                      &next, sizeof (struct pthread *)) != PS_OK)
74         return TD_ERR;  /* XXX Other error value?  */
75
76       if (next == thp)
77         return TD_DBERR;
78
79       if (thp == th->th_unique)
80         {
81           /* PREVP points at this thread, splice it out.  */
82           if (prevp == (char *) next + offsetof (struct pthread, nextevent))
83             return TD_DBERR;
84
85           if (ps_pdwrite (th->th_ta_p->ph, prevp, &next, sizeof next) != PS_OK)
86             return TD_ERR;      /* XXX Other error value?  */
87
88           /* Now clear this thread's own next pointer so it's not dangling
89              when the thread resumes and then chains on for its next event.  */
90           next = NULL;
91           if (ps_pdwrite (th->th_ta_p->ph,
92                           (char *) thp + offsetof (struct pthread, nextevent),
93                           &next, sizeof next) != PS_OK)
94             return TD_ERR;      /* XXX Other error value?  */
95
96           return TD_OK;
97         }
98
99       prevp = (char *) thp + offsetof (struct pthread, nextevent);
100       thp = next;
101     }
102
103   /* Ack!  This should not happen.  */
104   return TD_DBERR;
105 }