138 try: |
138 try: |
139 self.clientLock.release() |
139 self.clientLock.release() |
140 except AssertionError: |
140 except AssertionError: |
141 pass |
141 pass |
142 |
142 |
143 def setCurrentThread(self, id): |
143 def setCurrentThread(self, threadId): |
144 """ |
144 """ |
145 Public method to set the current thread. |
145 Public method to set the current thread. |
146 |
146 |
147 @param id the id the current thread should be set to. |
147 @param threadId the id the current thread should be set to. |
148 @type int |
148 @type int |
149 """ |
149 """ |
150 try: |
150 try: |
151 self.lockClient() |
151 self.lockClient() |
152 if id is None: |
152 if threadId is None: |
153 self.currentThread = None |
153 self.currentThread = None |
154 else: |
154 else: |
155 self.currentThread = self.threads.get(id) |
155 self.currentThread = self.threads.get(threadId) |
156 finally: |
156 finally: |
157 self.unlockClient() |
157 self.unlockClient() |
158 |
158 |
159 def dumpThreadList(self): |
159 def dumpThreadList(self): |
160 """ |
160 """ |
165 if len(self.threads) > 1: |
165 if len(self.threads) > 1: |
166 currentId = _thread.get_ident() |
166 currentId = _thread.get_ident() |
167 # update thread names set by user (threading.setName) |
167 # update thread names set by user (threading.setName) |
168 threadNames = {t.ident: t.getName() for t in threading.enumerate()} |
168 threadNames = {t.ident: t.getName() for t in threading.enumerate()} |
169 |
169 |
170 for id, thd in self.threads.items(): |
170 for threadId, thd in self.threads.items(): |
171 d = {"id": id} |
171 d = {"id": threadId} |
172 try: |
172 try: |
173 d["name"] = threadNames.get(id, thd.name) |
173 d["name"] = threadNames.get(threadId, thd.name) |
174 d["broken"] = thd.isBroken |
174 d["broken"] = thd.isBroken |
175 except Exception: |
175 except Exception: |
176 d["name"] = 'UnknownThread' |
176 d["name"] = 'UnknownThread' |
177 d["broken"] = False |
177 d["broken"] = False |
178 |
178 |
213 def updateThreadList(self): |
213 def updateThreadList(self): |
214 """ |
214 """ |
215 Public method to update the list of running threads. |
215 Public method to update the list of running threads. |
216 """ |
216 """ |
217 frames = sys._current_frames() |
217 frames = sys._current_frames() |
218 for id, frame in frames.items(): |
218 for threadId, frame in frames.items(): |
219 # skip our own timer thread |
219 # skip our own timer thread |
220 if frame.f_code.co_name == '__eventPollTimer': |
220 if frame.f_code.co_name == '__eventPollTimer': |
221 continue |
221 continue |
222 |
222 |
223 # Unknown thread |
223 # Unknown thread |
224 if id not in self.threads: |
224 if threadId not in self.threads: |
225 newThread = DebugBase(self) |
225 newThread = DebugBase(self) |
226 name = 'Thread-{0}'.format(self.threadNumber) |
226 name = 'Thread-{0}'.format(self.threadNumber) |
227 self.threadNumber += 1 |
227 self.threadNumber += 1 |
228 |
228 |
229 newThread.id = id |
229 newThread.id = threadId |
230 newThread.name = name |
230 newThread.name = name |
231 self.threads[id] = newThread |
231 self.threads[threadId] = newThread |
232 |
232 |
233 # adjust current frame |
233 # adjust current frame |
234 if "__pypy__" not in sys.builtin_module_names: |
234 if "__pypy__" not in sys.builtin_module_names: |
235 # Don't update with None |
235 # Don't update with None |
236 currentFrame = self.getExecutedFrame(frame) |
236 currentFrame = self.getExecutedFrame(frame) |
237 if (currentFrame is not None and |
237 if (currentFrame is not None and |
238 self.threads[id].isBroken is False): |
238 self.threads[threadId].isBroken is False): |
239 self.threads[id].currentFrame = currentFrame |
239 self.threads[threadId].currentFrame = currentFrame |
240 |
240 |
241 # Clean up obsolet because terminated threads |
241 # Clean up obsolet because terminated threads |
242 self.threads = {id_: thrd for id_, thrd in self.threads.items() |
242 self.threads = {id_: thrd for id_, thrd in self.threads.items() |
243 if id_ in frames} |
243 if id_ in frames} |
244 |
244 |