2010-06-28 Phil Muldoon <pmuldoon@redhat.com>
[deliverable/binutils-gdb.git] / gdb / python / py-infthread.c
CommitLineData
595939de
PM
1/* Python interface to inferior threads.
2
3 Copyright (C) 2009, 2010 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
26static 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
41thread_object *
42create_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
59static void
60thpy_dealloc (PyObject *self)
61{
62 Py_DECREF (((thread_object *) self)->inf_obj);
63 self->ob_type->tp_free (self);
64}
65
66static PyObject *
67thpy_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. */
78static PyObject *
79thpy_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. */
105static PyObject *
106thpy_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. */
125static PyObject *
126thpy_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. */
140static PyObject *
141thpy_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. */
155static PyObject *
156thpy_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. */
172PyObject *
173gdbpy_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
189void
190gdbpy_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
202static 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
211static PyMethodDef thread_object_methods[] =
212{
213 { "switch", thpy_switch, METH_NOARGS,
214 "switch ()\n\
215Makes this the GDB selected thread." },
216 { "is_stopped", thpy_is_stopped, METH_NOARGS,
217 "is_stopped () -> Boolean\n\
218Return whether the thread is stopped." },
219 { "is_running", thpy_is_running, METH_NOARGS,
220 "is_running () -> Boolean\n\
221Return whether the thread is running." },
222 { "is_exited", thpy_is_exited, METH_NOARGS,
223 "is_exited () -> Boolean\n\
224Return whether the thread is exited." },
225
226 { NULL }
227};
228
229static 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.04024 seconds and 4 git commands to generate.