Change prototype of test_in_mod1.
[kopensolaris-gnu/glibc.git] / linuxthreads_db / td_ta_event_getmsg.c
1 /* Retrieve event.
2    Copyright (C) 1999, 2001, 2002 Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
4    Contributed by Ulrich Drepper <drepper@cygnus.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 #include <linuxthreads/internals.h>
26
27
28 td_err_e
29 td_ta_event_getmsg (const td_thragent_t *ta, td_event_msg_t *msg)
30 {
31   /* XXX I cannot think of another way but using a static variable.  */
32   static td_thrhandle_t th;
33   td_eventbuf_t event;
34   psaddr_t addr;
35
36   LOG ("td_ta_event_getmsg");
37
38   /* Test whether the TA parameter is ok.  */
39   if (! ta_ok (ta))
40     return TD_BADTA;
41
42   /* Get the pointer to the thread descriptor with the last event.  */
43   if (ps_pdread (ta->ph, ta->pthread_last_event,
44                  &addr, sizeof (void *)) != PS_OK)
45     return TD_ERR;      /* XXX Other error value?  */
46
47   /* If the pointer is NULL no event occurred.  */
48   if (addr == 0)
49     return TD_NOMSG;
50
51   /* Read the even structure from the target.  */
52   if (ps_pdread (ta->ph,
53                  ((char *) addr
54                   + offsetof (struct _pthread_descr_struct, p_eventbuf)),
55                  &event, sizeof (td_eventbuf_t)) != PS_OK)
56     return TD_ERR;      /* XXX Other error value?  */
57
58   /* Check whether an event occurred.  */
59   if (event.eventnum == TD_EVENT_NONE)
60     {
61       /* Oh well, this means the last event was already read.  So
62          we have to look for any other event.  */
63       struct pthread_handle_struct handles[ta->pthread_threads_max];
64       int num;
65       int i;
66
67       /* Read the number of currently active threads.  */
68       if (ps_pdread (ta->ph, ta->pthread_handles_num, &num, sizeof (int))
69           != PS_OK)
70         return TD_ERR;  /* XXX Other error value?  */
71
72       /* Now read the handles.  */
73       if (ps_pdread (ta->ph, ta->handles, handles,
74                      ta->pthread_threads_max * sizeof (handles[0])) != PS_OK)
75         return TD_ERR;  /* XXX Other error value?  */
76
77       for (i = 0; i < ta->pthread_threads_max && num > 0; ++i)
78         {
79           if (handles[i].h_descr == NULL)
80             /* No entry here.  */
81             continue;
82
83           /* First count this active thread.  */
84           --num;
85
86           if (handles[i].h_descr == addr)
87             /* We already handled this.  */
88             continue;
89
90           /* Read the event data for this thread.  */
91           if (ps_pdread (ta->ph,
92                          ((char *) handles[i].h_descr
93                           + offsetof (struct _pthread_descr_struct,
94                                       p_eventbuf)),
95                          &event, sizeof (td_eventbuf_t)) != PS_OK)
96             return TD_ERR;
97
98           if (event.eventnum != TD_EVENT_NONE)
99             {
100               /* We found a thread with an unreported event.  */
101               addr = handles[i].h_descr;
102               break;
103             }
104         }
105
106       /* If we haven't found any other event signal this to the user.  */
107       if (event.eventnum == TD_EVENT_NONE)
108         return TD_NOMSG;
109     }
110
111   /* Generate the thread descriptor.  */
112   th.th_ta_p = (td_thragent_t *) ta;
113   th.th_unique = addr;
114
115   /* Fill the user's data structure.  */
116   msg->event = event.eventnum;
117   msg->th_p = &th;
118   msg->msg.data = (uintptr_t) event.eventdata;
119
120   /* And clear the event message in the target.  */
121   memset (&event, '\0', sizeof (td_eventbuf_t));
122   if (ps_pdwrite (ta->ph,
123                   ((char *) addr
124                    + offsetof (struct _pthread_descr_struct, p_eventbuf)),
125                   &event, sizeof (td_eventbuf_t)) != PS_OK)
126     return TD_ERR;      /* XXX Other error value?  */
127
128   return TD_OK;
129 }