|
@@ -356,6 +356,30 @@ static void process_pending_task(connection_t *cpuworker) {
|
|
|
log_fn(LOG_WARN,"assign_to_cpuworker failed. Ignoring.");
|
|
|
}
|
|
|
|
|
|
+#define CPUWORKER_BUSY_TIMEOUT 100 /* seconds */
|
|
|
+
|
|
|
+static void
|
|
|
+cull_wedged_cpuworkers(void) {
|
|
|
+ connection_t **carray;
|
|
|
+ connection_t *conn;
|
|
|
+ int n_conns, i;
|
|
|
+ time_t now = time(NULL);
|
|
|
+
|
|
|
+ get_connection_array(&carray, &n_conns);
|
|
|
+ for (i = 0; i < n_conns; ++i) {
|
|
|
+ conn = carray[i];
|
|
|
+ if (!conn->marked_for_close &&
|
|
|
+ conn->type == CONN_TYPE_CPUWORKER &&
|
|
|
+ conn->state == CPUWORKER_STATE_BUSY_ONION &&
|
|
|
+ conn->timestamp_lastwritten + CPUWORKER_BUSY_TIMEOUT > now) {
|
|
|
+ log_fn(LOG_NOTICE,"Bug: closing wedged cpuworker. Can somebody find the bug?");
|
|
|
+ num_cpuworkers_busy--;
|
|
|
+ num_cpuworkers--;
|
|
|
+ connection_mark_for_close(conn);
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
/** If cpuworker is defined, assert that he's idle, and use him. Else,
|
|
|
* look for an idle cpuworker and use him. If none idle, queue task onto
|
|
|
* the pending onion list and return.
|
|
@@ -369,6 +393,9 @@ int assign_to_cpuworker(connection_t *cpuworker, unsigned char question_type,
|
|
|
|
|
|
tor_assert(question_type == CPUWORKER_TASK_ONION);
|
|
|
|
|
|
+ cull_wedged_cpuworkers();
|
|
|
+ spawn_enough_cpuworkers();
|
|
|
+
|
|
|
if (question_type == CPUWORKER_TASK_ONION) {
|
|
|
circ = task;
|
|
|
|