Skip to content

Commit fa16068

Browse files
committed
Bugfix: SignalSync leaks and wrong status of global priority bthread
1 parent 93ec09a commit fa16068

3 files changed

Lines changed: 23 additions & 7 deletions

File tree

src/bthread/task_control.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ int TaskControl::init(int concurrency) {
209209
"bthread_worker_usage", tag_str, _tagged_cumulated_worker_time[i], 1));
210210
_tagged_nbthreads.push_back(new bvar::Adder<int64_t>("bthread_count", tag_str));
211211
if (_priority_queues[i].init(BTHREAD_MAX_CONCURRENCY) != 0) {
212-
LOG(FATAL) << "Fail to init _priority_q";
212+
LOG(ERROR) << "Fail to init _priority_q";
213213
return -1;
214214
}
215215
}

src/bthread/task_group.cpp

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -496,7 +496,7 @@ int TaskGroup::start_foreground(TaskGroup** pg,
496496
(bool)(using_attr.flags & BTHREAD_NOSIGNAL)
497497
};
498498
g->set_remained(fn, &args);
499-
TaskGroup::sched_to(pg, m->tid);
499+
sched_to(pg, m->tid);
500500
}
501501
return 0;
502502
}
@@ -784,6 +784,11 @@ void TaskGroup::ready_to_run(TaskMeta* meta, bool nosignal) {
784784
#ifdef BRPC_BTHREAD_TRACER
785785
_control->_task_tracer.set_status(TASK_STATUS_READY, meta);
786786
#endif // BRPC_BTHREAD_TRACER
787+
if (meta->attr.flags & BTHREAD_GLOBAL_PRIORITY) {
788+
_control->push_priority_queue(_tag, meta->tid);
789+
return;
790+
}
791+
787792
push_rq(meta->tid);
788793
if (nosignal) {
789794
++_num_nosignal;
@@ -808,6 +813,11 @@ void TaskGroup::ready_to_run_remote(TaskMeta* meta, bool nosignal) {
808813
#ifdef BRPC_BTHREAD_TRACER
809814
_control->_task_tracer.set_status(TASK_STATUS_READY, meta);
810815
#endif // BRPC_BTHREAD_TRACER
816+
if (meta->attr.flags & BTHREAD_GLOBAL_PRIORITY) {
817+
_control->push_priority_queue(_tag, meta->tid);
818+
return;
819+
}
820+
811821
_remote_rq._mutex.lock();
812822
while (!_remote_rq.push_locked(meta->tid)) {
813823
flush_nosignal_tasks_remote_locked(_remote_rq._mutex);
@@ -870,6 +880,10 @@ void TaskGroup::ready_to_run_in_worker_ignoresignal(void* args_in) {
870880

871881
void TaskGroup::priority_to_run(void* args_in) {
872882
ReadyToRunArgs* args = static_cast<ReadyToRunArgs*>(args_in);
883+
#ifdef BRPC_BTHREAD_TRACER
884+
tls_task_group->_control->_task_tracer.set_status(
885+
TASK_STATUS_READY, args->meta);
886+
#endif // BRPC_BTHREAD_TRACER
873887
return tls_task_group->control()->push_priority_queue(args->tag, args->meta->tid);
874888
}
875889

@@ -1031,14 +1045,15 @@ int TaskGroup::interrupt(bthread_t tid, TaskControl* c, bthread_tag_t tag) {
10311045
}
10321046
} else if (sleep_id != 0) {
10331047
if (get_global_timer_thread()->unschedule(sleep_id) == 0) {
1034-
bthread::TaskGroup* g = bthread::tls_task_group;
1048+
TaskGroup* g = tls_task_group;
1049+
TaskMeta* m = address_meta(tid);
10351050
if (g) {
1036-
g->ready_to_run(TaskGroup::address_meta(tid));
1051+
g->ready_to_run(m);
10371052
} else {
10381053
if (!c) {
10391054
return EINVAL;
10401055
}
1041-
c->choose_one_group(tag)->ready_to_run_remote(TaskGroup::address_meta(tid));
1056+
c->choose_one_group(tag)->ready_to_run_remote(m);
10421057
}
10431058
}
10441059
}

src/bthread/task_tracer.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -353,8 +353,9 @@ bool TaskTracer::RegisterSignalHandler() {
353353
// Caution: This function should be async-signal-safety.
354354
void TaskTracer::SignalHandler(int, siginfo_t* info, void* context) {
355355
ErrnoGuard guard;
356+
// Ref has been taken before the signal is sent, so no need to add ref here.
356357
butil::intrusive_ptr<SignalSync> signal_sync(
357-
static_cast<SignalSync*>(info->si_value.sival_ptr));
358+
static_cast<SignalSync*>(info->si_value.sival_ptr), false);
358359
if (NULL == signal_sync || NULL == signal_sync->result) {
359360
// The signal is not from Tracer, such as TaskControl, do nothing.
360361
return;
@@ -408,7 +409,7 @@ TaskTracer::Result TaskTracer::SignalTrace(pid_t tid) {
408409
auto iter = std::remove_if(
409410
_inuse_signal_syncs.begin(), _inuse_signal_syncs.end(),
410411
[](butil::intrusive_ptr<SignalSync>& sync) {
411-
return sync->ref_count() == 0;
412+
return sync->ref_count() == 1;
412413
});
413414
_inuse_signal_syncs.erase(iter, _inuse_signal_syncs.end());
414415

0 commit comments

Comments
 (0)