Rewrote user_debug_thread_deleted():
* It was broken since the support for debugger handovers. Using debugger_write() couldn't work, since the thread didn't belong to the debugged team anymore (but to the kernel) and thus getting the debug info for team would always fail. This makes B_DEBUGGER_MESSAGE_THREAD_DELETED notifications work again. * Allow the thread to block. Locking/writing to the port was non-blocking before, but there shouldn't be a problem, if the thread has to wait. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@31076 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -950,25 +950,24 @@ user_debug_thread_created(thread_id threadID)
|
|||||||
void
|
void
|
||||||
user_debug_thread_deleted(team_id teamID, thread_id threadID)
|
user_debug_thread_deleted(team_id teamID, thread_id threadID)
|
||||||
{
|
{
|
||||||
|
// Things are a bit complicated here, since this thread no longer belongs to
|
||||||
|
// the debugged team (but to the kernel). So we can't use debugger_write().
|
||||||
|
|
||||||
// get the team debug flags and debugger port
|
// get the team debug flags and debugger port
|
||||||
cpu_status state = disable_interrupts();
|
InterruptsSpinLocker teamLocker(gTeamSpinlock);
|
||||||
GRAB_TEAM_LOCK();
|
|
||||||
|
|
||||||
struct team *team = team_get_team_struct_locked(teamID);
|
struct team *team = team_get_team_struct_locked(teamID);
|
||||||
|
if (team == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
int32 teamDebugFlags = 0;
|
SpinLocker debugInfoLocker(team->debug_info.lock);
|
||||||
port_id debuggerPort = -1;
|
|
||||||
if (team) {
|
|
||||||
GRAB_TEAM_DEBUG_INFO_LOCK(team->debug_info);
|
|
||||||
|
|
||||||
teamDebugFlags = atomic_get(&team->debug_info.flags);
|
int32 teamDebugFlags = atomic_get(&team->debug_info.flags);
|
||||||
debuggerPort = team->debug_info.debugger_port;
|
port_id debuggerPort = team->debug_info.debugger_port;
|
||||||
|
sem_id writeLock = team->debug_info.debugger_write_lock;
|
||||||
|
|
||||||
RELEASE_TEAM_DEBUG_INFO_LOCK(team->debug_info);
|
debugInfoLocker.Unlock();
|
||||||
}
|
teamLocker.Unlock();
|
||||||
|
|
||||||
RELEASE_TEAM_LOCK();
|
|
||||||
restore_interrupts(state);
|
|
||||||
|
|
||||||
// check, if a debugger is installed and is interested in thread events
|
// check, if a debugger is installed and is interested in thread events
|
||||||
if (~teamDebugFlags
|
if (~teamDebugFlags
|
||||||
@@ -976,16 +975,41 @@ user_debug_thread_deleted(team_id teamID, thread_id threadID)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// notify the debugger
|
// acquire the debugger write lock
|
||||||
if (debuggerPort >= 0) {
|
status_t error = acquire_sem_etc(writeLock, 1, B_KILL_CAN_INTERRUPT, 0);
|
||||||
|
if (error != B_OK)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// re-get the team debug info -- we need to check whether anything changed
|
||||||
|
teamLocker.Lock();
|
||||||
|
|
||||||
|
team = team_get_team_struct_locked(teamID);
|
||||||
|
if (team == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
debugInfoLocker.Lock();
|
||||||
|
|
||||||
|
teamDebugFlags = atomic_get(&team->debug_info.flags);
|
||||||
|
port_id newDebuggerPort = team->debug_info.debugger_port;
|
||||||
|
|
||||||
|
debugInfoLocker.Unlock();
|
||||||
|
teamLocker.Unlock();
|
||||||
|
|
||||||
|
// Send the message only if the debugger hasn't changed in the meantime or
|
||||||
|
// the team is about to be handed over.
|
||||||
|
if (newDebuggerPort == debuggerPort
|
||||||
|
|| (teamDebugFlags & B_TEAM_DEBUG_DEBUGGER_HANDOVER) == 0) {
|
||||||
debug_thread_deleted message;
|
debug_thread_deleted message;
|
||||||
message.origin.thread = threadID;
|
message.origin.thread = threadID;
|
||||||
message.origin.team = teamID;
|
message.origin.team = teamID;
|
||||||
message.origin.nub_port = -1;
|
message.origin.nub_port = -1;
|
||||||
debugger_write(debuggerPort, B_DEBUGGER_MESSAGE_THREAD_DELETED,
|
|
||||||
&message, sizeof(message), true);
|
write_port_etc(debuggerPort, B_DEBUGGER_MESSAGE_THREAD_DELETED,
|
||||||
// TODO: Would it be OK to wait here?
|
&message, sizeof(message), B_KILL_CAN_INTERRUPT, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// release the debugger write lock
|
||||||
|
release_sem(writeLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user