mirror of
https://github.com/strongswan/strongswan.git
synced 2025-10-04 00:00:14 -04:00
Merge branch 'initiate-cancel'
Allow proper shutdown if a deadlock is caused by too many concurrent blocking initiation requests. References strongswan/strongswan#2776
This commit is contained in:
commit
688b9e27d5
@ -400,6 +400,8 @@ METHOD(job_t, destroy_job, void,
|
|||||||
{
|
{
|
||||||
this->listener.lock->destroy(this->listener.lock);
|
this->listener.lock->destroy(this->listener.lock);
|
||||||
DESTROY_IF(this->listener.done);
|
DESTROY_IF(this->listener.done);
|
||||||
|
DESTROY_IF(this->listener.child_cfg);
|
||||||
|
DESTROY_IF(this->listener.peer_cfg);
|
||||||
free(this);
|
free(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -416,14 +418,11 @@ METHOD(job_t, initiate_execute, job_requeue_t,
|
|||||||
{
|
{
|
||||||
ike_sa_t *ike_sa;
|
ike_sa_t *ike_sa;
|
||||||
interface_listener_t *listener = &job->listener;
|
interface_listener_t *listener = &job->listener;
|
||||||
peer_cfg_t *peer_cfg = listener->peer_cfg;
|
|
||||||
|
|
||||||
ike_sa = charon->ike_sa_manager->checkout_by_config(charon->ike_sa_manager,
|
ike_sa = charon->ike_sa_manager->checkout_by_config(charon->ike_sa_manager,
|
||||||
peer_cfg);
|
listener->peer_cfg);
|
||||||
peer_cfg->destroy(peer_cfg);
|
|
||||||
if (!ike_sa)
|
if (!ike_sa)
|
||||||
{
|
{
|
||||||
DESTROY_IF(listener->child_cfg);
|
|
||||||
listener->status = FAILED;
|
listener->status = FAILED;
|
||||||
listener_done(listener);
|
listener_done(listener);
|
||||||
return JOB_REQUEUE_NONE;
|
return JOB_REQUEUE_NONE;
|
||||||
@ -449,7 +448,6 @@ METHOD(job_t, initiate_execute, job_requeue_t,
|
|||||||
"%d exceeds limit of %d", half_open, limit_half_open);
|
"%d exceeds limit of %d", half_open, limit_half_open);
|
||||||
charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager,
|
charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager,
|
||||||
ike_sa);
|
ike_sa);
|
||||||
DESTROY_IF(listener->child_cfg);
|
|
||||||
listener->status = INVALID_STATE;
|
listener->status = INVALID_STATE;
|
||||||
listener_done(listener);
|
listener_done(listener);
|
||||||
return JOB_REQUEUE_NONE;
|
return JOB_REQUEUE_NONE;
|
||||||
@ -468,7 +466,6 @@ METHOD(job_t, initiate_execute, job_requeue_t,
|
|||||||
"limit of %d", jobs, limit_job_load);
|
"limit of %d", jobs, limit_job_load);
|
||||||
charon->ike_sa_manager->checkin_and_destroy(
|
charon->ike_sa_manager->checkin_and_destroy(
|
||||||
charon->ike_sa_manager, ike_sa);
|
charon->ike_sa_manager, ike_sa);
|
||||||
DESTROY_IF(listener->child_cfg);
|
|
||||||
listener->status = INVALID_STATE;
|
listener->status = INVALID_STATE;
|
||||||
listener_done(listener);
|
listener_done(listener);
|
||||||
return JOB_REQUEUE_NONE;
|
return JOB_REQUEUE_NONE;
|
||||||
@ -476,6 +473,10 @@ METHOD(job_t, initiate_execute, job_requeue_t,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (listener->child_cfg)
|
||||||
|
{
|
||||||
|
listener->child_cfg->get_ref(listener->child_cfg);
|
||||||
|
}
|
||||||
if (ike_sa->initiate(ike_sa, listener->child_cfg, NULL) == SUCCESS)
|
if (ike_sa->initiate(ike_sa, listener->child_cfg, NULL) == SUCCESS)
|
||||||
{
|
{
|
||||||
if (!listener->logger.callback ||
|
if (!listener->logger.callback ||
|
||||||
|
@ -480,6 +480,15 @@ static bool do_read(private_vici_socket_t *this, entry_t *entry,
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clear the given chunk and free it
|
||||||
|
*/
|
||||||
|
static void destroy_request_chunk(chunk_t *chunk)
|
||||||
|
{
|
||||||
|
chunk_clear(chunk);
|
||||||
|
free(chunk);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Callback processing incoming requests in strict order
|
* Callback processing incoming requests in strict order
|
||||||
*/
|
*/
|
||||||
@ -487,7 +496,7 @@ CALLBACK(process_queue, job_requeue_t,
|
|||||||
entry_selector_t *sel)
|
entry_selector_t *sel)
|
||||||
{
|
{
|
||||||
entry_t *entry;
|
entry_t *entry;
|
||||||
chunk_t chunk;
|
chunk_t *chunk;
|
||||||
bool found;
|
bool found;
|
||||||
u_int id;
|
u_int id;
|
||||||
|
|
||||||
@ -499,7 +508,8 @@ CALLBACK(process_queue, job_requeue_t,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
found = array_remove(entry->queue, ARRAY_HEAD, &chunk);
|
INIT(chunk);
|
||||||
|
found = array_remove(entry->queue, ARRAY_HEAD, chunk);
|
||||||
if (!found)
|
if (!found)
|
||||||
{
|
{
|
||||||
entry->has_processor = FALSE;
|
entry->has_processor = FALSE;
|
||||||
@ -508,11 +518,12 @@ CALLBACK(process_queue, job_requeue_t,
|
|||||||
put_entry(sel->this, entry, TRUE, FALSE);
|
put_entry(sel->this, entry, TRUE, FALSE);
|
||||||
if (!found)
|
if (!found)
|
||||||
{
|
{
|
||||||
|
free(chunk);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
thread_cleanup_push((void*)chunk_clear, &chunk);
|
thread_cleanup_push((void*)destroy_request_chunk, chunk);
|
||||||
sel->this->inbound(sel->this->user, id, chunk);
|
sel->this->inbound(sel->this->user, id, *chunk);
|
||||||
thread_cleanup_pop(TRUE);
|
thread_cleanup_pop(TRUE);
|
||||||
}
|
}
|
||||||
return JOB_REQUEUE_NONE;
|
return JOB_REQUEUE_NONE;
|
||||||
@ -552,8 +563,8 @@ CALLBACK(on_read, bool,
|
|||||||
.id = entry->id,
|
.id = entry->id,
|
||||||
);
|
);
|
||||||
lib->processor->queue_job(lib->processor,
|
lib->processor->queue_job(lib->processor,
|
||||||
(job_t*)callback_job_create(process_queue,
|
(job_t*)callback_job_create(process_queue, sel,
|
||||||
sel, free, NULL));
|
free, callback_job_cancel_thread));
|
||||||
entry->has_processor = TRUE;
|
entry->has_processor = TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user