vici: Send all queued messages during shutdown
This ensures that e.g. ike/child-updown messages are sent that were queued but couldn't be sent (even the job to enable to on_write() callback requires a worker thread that's not around anymore during shutdown). References #3602.
This commit is contained in:
parent
6586f07162
commit
ef636316d2
|
@ -310,7 +310,7 @@ static void disconnect(private_vici_socket_t *this, u_int id)
|
|||
* Write queued output data
|
||||
*/
|
||||
static bool do_write(private_vici_socket_t *this, entry_t *entry,
|
||||
stream_t *stream, char *errmsg, size_t errlen)
|
||||
stream_t *stream, char *errmsg, size_t errlen, bool block)
|
||||
{
|
||||
msg_buf_t *out;
|
||||
ssize_t len;
|
||||
|
@ -321,7 +321,7 @@ static bool do_write(private_vici_socket_t *this, entry_t *entry,
|
|||
while (out->hdrlen < sizeof(out->hdr))
|
||||
{
|
||||
len = stream->write(stream, out->hdr + out->hdrlen,
|
||||
sizeof(out->hdr) - out->hdrlen, FALSE);
|
||||
sizeof(out->hdr) - out->hdrlen, block);
|
||||
if (len == 0)
|
||||
{
|
||||
return FALSE;
|
||||
|
@ -343,7 +343,7 @@ static bool do_write(private_vici_socket_t *this, entry_t *entry,
|
|||
while (out->buf.len > out->done)
|
||||
{
|
||||
len = stream->write(stream, out->buf.ptr + out->done,
|
||||
out->buf.len - out->done, FALSE);
|
||||
out->buf.len - out->done, block);
|
||||
if (len == 0)
|
||||
{
|
||||
snprintf(errmsg, errlen, "premature vici disconnect");
|
||||
|
@ -383,7 +383,7 @@ CALLBACK(on_write, bool,
|
|||
entry = find_entry(this, stream, 0, FALSE, TRUE);
|
||||
if (entry)
|
||||
{
|
||||
ret = do_write(this, entry, stream, errmsg, sizeof(errmsg));
|
||||
ret = do_write(this, entry, stream, errmsg, sizeof(errmsg), FALSE);
|
||||
if (ret)
|
||||
{
|
||||
/* unregister if we have no more messages to send */
|
||||
|
@ -656,10 +656,30 @@ METHOD(vici_socket_t, send_, void,
|
|||
}
|
||||
}
|
||||
|
||||
CALLBACK(flush_messages, void,
|
||||
entry_t *entry, va_list args)
|
||||
{
|
||||
private_vici_socket_t *this;
|
||||
char errmsg[256] = "";
|
||||
bool ret;
|
||||
|
||||
VA_ARGS_VGET(args, this);
|
||||
|
||||
/* no need for any locking as no other threads are running, the connections
|
||||
* all get disconneted afterwards, so error handling is simple too */
|
||||
ret = do_write(this, entry, entry->stream, errmsg, sizeof(errmsg), TRUE);
|
||||
|
||||
if (!ret && errmsg[0])
|
||||
{
|
||||
DBG1(DBG_CFG, errmsg);
|
||||
}
|
||||
}
|
||||
|
||||
METHOD(vici_socket_t, destroy, void,
|
||||
private_vici_socket_t *this)
|
||||
{
|
||||
DESTROY_IF(this->service);
|
||||
this->connections->invoke_function(this->connections, flush_messages, this);
|
||||
this->connections->destroy_function(this->connections, destroy_entry);
|
||||
this->mutex->destroy(this->mutex);
|
||||
free(this);
|
||||
|
|
Loading…
Reference in New Issue