run copyright.sh for 2011.
[deliverable/binutils-gdb.git] / gdb / python / py-infthread.c
1 /* Python interface to inferior threads.
2
3 Copyright (C) 2009, 2010, 2011 Free Software Foundation, Inc.
4
5 This file is part of GDB.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
19
20 #include "defs.h"
21 #include "exceptions.h"
22 #include "gdbthread.h"
23 #include "inferior.h"
24 #include "python-internal.h"
25
26 static PyTypeObject thread_object_type;
27
28 /* Require that INFERIOR be a valid inferior ID. */
29 #define THPY_REQUIRE_VALID(Thread) \
30 do { \
31 if (!Thread->thread) \
32 { \
33 PyErr_SetString (PyExc_RuntimeError, \
34 _("Thread no longer exists.")); \
35 return NULL; \
36 } \
37 } while (0)
38
39
40
41 thread_object *
42 create_thread_object (struct thread_info *tp)
43 {
44 thread_object *thread_obj;
45
46 thread_obj = PyObject_New (thread_object, &thread_object_type);
47 if (!thread_obj)
48 return NULL;
49
50 thread_obj->thread = tp;
51 thread_obj->inf_obj = find_inferior_object (PIDGET (tp->ptid));
52 Py_INCREF (thread_obj->inf_obj);
53
54 return thread_obj;
55 }
56
57
58
59 static void
60 thpy_dealloc (PyObject *self)
61 {
62 Py_DECREF (((thread_object *) self)->inf_obj);
63 self->ob_type->tp_free (self);
64 }
65
66 static PyObject *
67 thpy_get_num (PyObject *self, void *closure)
68 {
69 thread_object *thread_obj = (thread_object *) self;
70
71 THPY_REQUIRE_VALID (thread_obj);
72
73 return PyLong_FromLong (thread_obj->thread->num);
74 }
75
76 /* Getter for InferiorThread.ptid -> (pid, lwp, tid).
77 Returns a tuple with the thread's ptid components. */
78 static PyObject *
79 thpy_get_ptid (PyObject *self, void *closure)
80 {
81 int pid;
82 long tid, lwp;
83 thread_object *thread_obj = (thread_object *) self;
84 PyObject *ret;
85
86 THPY_REQUIRE_VALID (thread_obj);
87
88 ret = PyTuple_New (3);
89 if (!ret)
90 return NULL;
91
92 pid = ptid_get_pid (thread_obj->thread->ptid);
93 lwp = ptid_get_lwp (thread_obj->thread->ptid);
94 tid = ptid_get_tid (thread_obj->thread->ptid);
95
96 PyTuple_SET_ITEM (ret, 0, PyInt_FromLong (pid));
97 PyTuple_SET_ITEM (ret, 1, PyInt_FromLong (lwp));
98 PyTuple_SET_ITEM (ret, 2, PyInt_FromLong (tid));
99
100 return ret;
101 }
102
103 /* Implementation of InferiorThread.switch ().
104 Makes this the GDB selected thread. */
105 static PyObject *
106 thpy_switch (PyObject *self, PyObject *args)
107 {
108 thread_object *thread_obj = (thread_object *) self;
109 struct cleanup *cleanup;
110 volatile struct gdb_exception except;
111
112 THPY_REQUIRE_VALID (thread_obj);
113
114 TRY_CATCH (except, RETURN_MASK_ALL)
115 {
116 switch_to_thread (thread_obj->thread->ptid);
117 }
118 GDB_PY_HANDLE_EXCEPTION (except);
119
120 Py_RETURN_NONE;
121 }
122
123 /* Implementation of InferiorThread.is_stopped () -> Boolean.
124 Return whether the thread is stopped. */
125 static PyObject *
126 thpy_is_stopped (PyObject *self, PyObject *args)
127 {
128 thread_object *thread_obj = (thread_object *) self;
129
130 THPY_REQUIRE_VALID (thread_obj);
131
132 if (is_stopped (thread_obj->thread->ptid))
133 Py_RETURN_TRUE;
134
135 Py_RETURN_FALSE;
136 }
137
138 /* Implementation of InferiorThread.is_running () -> Boolean.
139 Return whether the thread is running. */
140 static PyObject *
141 thpy_is_running (PyObject *self, PyObject *args)
142 {
143 thread_object *thread_obj = (thread_object *) self;
144
145 THPY_REQUIRE_VALID (thread_obj);
146
147 if (is_running (thread_obj->thread->ptid))
148 Py_RETURN_TRUE;
149
150 Py_RETURN_FALSE;
151 }
152
153 /* Implementation of InferiorThread.is_exited () -> Boolean.
154 Return whether the thread is exited. */
155 static PyObject *
156 thpy_is_exited (PyObject *self, PyObject *args)
157 {
158 thread_object *thread_obj = (thread_object *) self;
159
160 THPY_REQUIRE_VALID (thread_obj);
161
162 if (is_exited (thread_obj->thread->ptid))
163 Py_RETURN_TRUE;
164
165 Py_RETURN_FALSE;
166 }
167
168
169
170 /* Implementation of gdb.selected_thread () -> gdb.InferiorThread.
171 Returns the selected thread object. */
172 PyObject *
173 gdbpy_selected_thread (PyObject *self, PyObject *args)
174 {
175 PyObject *thread_obj;
176
177 thread_obj = (PyObject *) find_thread_object (inferior_ptid);
178 if (thread_obj)
179 {
180 Py_INCREF (thread_obj);
181 return thread_obj;
182 }
183
184 Py_RETURN_NONE;
185 }
186
187
188
189 void
190 gdbpy_initialize_thread (void)
191 {
192 if (PyType_Ready (&thread_object_type) < 0)
193 return;
194
195 Py_INCREF (&thread_object_type);
196 PyModule_AddObject (gdb_module, "InferiorThread",
197 (PyObject *) &thread_object_type);
198 }
199
200
201
202 static PyGetSetDef thread_object_getset[] =
203 {
204 { "num", thpy_get_num, NULL, "ID of the thread, as assigned by GDB.", NULL },
205 { "ptid", thpy_get_ptid, NULL, "ID of the thread, as assigned by the OS.",
206 NULL },
207
208 { NULL }
209 };
210
211 static PyMethodDef thread_object_methods[] =
212 {
213 { "switch", thpy_switch, METH_NOARGS,
214 "switch ()\n\
215 Makes this the GDB selected thread." },
216 { "is_stopped", thpy_is_stopped, METH_NOARGS,
217 "is_stopped () -> Boolean\n\
218 Return whether the thread is stopped." },
219 { "is_running", thpy_is_running, METH_NOARGS,
220 "is_running () -> Boolean\n\
221 Return whether the thread is running." },
222 { "is_exited", thpy_is_exited, METH_NOARGS,
223 "is_exited () -> Boolean\n\
224 Return whether the thread is exited." },
225
226 { NULL }
227 };
228
229 static PyTypeObject thread_object_type =
230 {
231 PyObject_HEAD_INIT (NULL)
232 0, /*ob_size*/
233 "gdb.InferiorThread", /*tp_name*/
234 sizeof (thread_object), /*tp_basicsize*/
235 0, /*tp_itemsize*/
236 thpy_dealloc, /*tp_dealloc*/
237 0, /*tp_print*/
238 0, /*tp_getattr*/
239 0, /*tp_setattr*/
240 0, /*tp_compare*/
241 0, /*tp_repr*/
242 0, /*tp_as_number*/
243 0, /*tp_as_sequence*/
244 0, /*tp_as_mapping*/
245 0, /*tp_hash */
246 0, /*tp_call*/
247 0, /*tp_str*/
248 0, /*tp_getattro*/
249 0, /*tp_setattro*/
250 0, /*tp_as_buffer*/
251 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_ITER, /*tp_flags*/
252 "GDB thread object", /* tp_doc */
253 0, /* tp_traverse */
254 0, /* tp_clear */
255 0, /* tp_richcompare */
256 0, /* tp_weaklistoffset */
257 0, /* tp_iter */
258 0, /* tp_iternext */
259 thread_object_methods, /* tp_methods */
260 0, /* tp_members */
261 thread_object_getset, /* tp_getset */
262 0, /* tp_base */
263 0, /* tp_dict */
264 0, /* tp_descr_get */
265 0, /* tp_descr_set */
266 0, /* tp_dictoffset */
267 0, /* tp_init */
268 0 /* tp_alloc */
269 };
This page took 0.037197 seconds and 5 git commands to generate.