fixed the early task termination issue in http-file.c
This commit is contained in:
parent
0d44a00953
commit
c7e989518f
@ -119,6 +119,8 @@ struct hio_svc_htts_task_t
|
|||||||
HIO_SVC_HTTS_TASK_HEADER;
|
HIO_SVC_HTTS_TASK_HEADER;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define HIO_SVC_HTTS_TASK_RC(task) ((task)->task_refcnt)
|
||||||
|
|
||||||
#define HIO_SVC_HTTS_TASK_RCUP(task) (++(task)->task_refcnt)
|
#define HIO_SVC_HTTS_TASK_RCUP(task) (++(task)->task_refcnt)
|
||||||
|
|
||||||
#define HIO_SVC_HTTS_TASK_RCDOWN(task_var) do { \
|
#define HIO_SVC_HTTS_TASK_RCDOWN(task_var) do { \
|
||||||
|
12
lib/hio.c
12
lib/hio.c
@ -159,6 +159,7 @@ void hio_fini (hio_t* hio)
|
|||||||
hio_dev_t* dev, * next_dev;
|
hio_dev_t* dev, * next_dev;
|
||||||
hio_dev_t diehard;
|
hio_dev_t diehard;
|
||||||
hio_oow_t i;
|
hio_oow_t i;
|
||||||
|
hio_oow_t nactdevs = 0, nhltdevs = 0, nzmbdevs = 0, ndieharddevs = 0; /* statistics */
|
||||||
|
|
||||||
hio->_fini_in_progress = 1;
|
hio->_fini_in_progress = 1;
|
||||||
|
|
||||||
@ -204,12 +205,14 @@ void hio_fini (hio_t* hio)
|
|||||||
while (!HIO_DEVL_IS_EMPTY(&hio->actdev))
|
while (!HIO_DEVL_IS_EMPTY(&hio->actdev))
|
||||||
{
|
{
|
||||||
hio_dev_kill (HIO_DEVL_FIRST_DEV(&hio->actdev));
|
hio_dev_kill (HIO_DEVL_FIRST_DEV(&hio->actdev));
|
||||||
|
nactdevs++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* kill all halted devices */
|
/* kill all halted devices */
|
||||||
while (!HIO_DEVL_IS_EMPTY(&hio->hltdev))
|
while (!HIO_DEVL_IS_EMPTY(&hio->hltdev))
|
||||||
{
|
{
|
||||||
hio_dev_kill (HIO_DEVL_FIRST_DEV(&hio->hltdev));
|
hio_dev_kill (HIO_DEVL_FIRST_DEV(&hio->hltdev));
|
||||||
|
nhltdevs++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* clean up all zombie devices */
|
/* clean up all zombie devices */
|
||||||
@ -219,7 +222,7 @@ void hio_fini (hio_t* hio)
|
|||||||
kill_and_free_device (dev, 1);
|
kill_and_free_device (dev, 1);
|
||||||
if (HIO_DEVL_FIRST_DEV(&hio->zmbdev) == dev)
|
if (HIO_DEVL_FIRST_DEV(&hio->zmbdev) == dev)
|
||||||
{
|
{
|
||||||
/* the deive has not been freed. go on to the next one */
|
/* the device has not been freed. go on to the next one */
|
||||||
next_dev = dev->dev_next;
|
next_dev = dev->dev_next;
|
||||||
|
|
||||||
/* remove the device from the zombie device list */
|
/* remove the device from the zombie device list */
|
||||||
@ -231,7 +234,11 @@ void hio_fini (hio_t* hio)
|
|||||||
|
|
||||||
dev = next_dev;
|
dev = next_dev;
|
||||||
}
|
}
|
||||||
else dev = HIO_DEVL_FIRST_DEV(&hio->zmbdev);
|
else
|
||||||
|
{
|
||||||
|
nzmbdevs++;
|
||||||
|
dev = HIO_DEVL_FIRST_DEV(&hio->zmbdev);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
while (!HIO_DEVL_IS_EMPTY(&diehard))
|
while (!HIO_DEVL_IS_EMPTY(&diehard))
|
||||||
@ -243,6 +250,7 @@ void hio_fini (hio_t* hio)
|
|||||||
HIO_ASSERT (hio, !(dev->dev_cap & (HIO_DEV_CAP_ACTIVE | HIO_DEV_CAP_HALTED | HIO_DEV_CAP_ZOMBIE)));
|
HIO_ASSERT (hio, !(dev->dev_cap & (HIO_DEV_CAP_ACTIVE | HIO_DEV_CAP_HALTED | HIO_DEV_CAP_ZOMBIE)));
|
||||||
HIO_DEVL_UNLINK_DEV (dev);
|
HIO_DEVL_UNLINK_DEV (dev);
|
||||||
kill_and_free_device (dev, 2);
|
kill_and_free_device (dev, 2);
|
||||||
|
ndieharddevs++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* purge scheduled timer jobs and kill the timer */
|
/* purge scheduled timer jobs and kill the timer */
|
||||||
|
@ -648,9 +648,7 @@ struct hdr_cbserter_ctx_t
|
|||||||
hio_oow_t vlen;
|
hio_oow_t vlen;
|
||||||
};
|
};
|
||||||
|
|
||||||
static hio_htb_pair_t* hdr_cbserter (
|
static hio_htb_pair_t* hdr_cbserter (hio_htb_t* htb, hio_htb_pair_t* pair, void* kptr, hio_oow_t klen, void* ctx)
|
||||||
hio_htb_t* htb, hio_htb_pair_t* pair,
|
|
||||||
void* kptr, hio_oow_t klen, void* ctx)
|
|
||||||
{
|
{
|
||||||
struct hdr_cbserter_ctx_t* tx = (struct hdr_cbserter_ctx_t*)ctx;
|
struct hdr_cbserter_ctx_t* tx = (struct hdr_cbserter_ctx_t*)ctx;
|
||||||
|
|
||||||
|
@ -720,14 +720,14 @@ static int bind_task_to_peer (file_t* file, hio_htre_t* req, const hio_bch_t* fi
|
|||||||
const hio_bch_t* actual_mime_type = mime_type;
|
const hio_bch_t* actual_mime_type = mime_type;
|
||||||
|
|
||||||
if (open_peer_with_mode(file, file_path, O_RDONLY, &status_code, (mime_type? HIO_NULL: &actual_mime_type)) <= -1 ||
|
if (open_peer_with_mode(file, file_path, O_RDONLY, &status_code, (mime_type? HIO_NULL: &actual_mime_type)) <= -1 ||
|
||||||
process_range_header(file, req, &status_code) <= -1) goto done_with_status_code;
|
process_range_header(file, req, &status_code) <= -1) goto oops_with_status_code;
|
||||||
|
|
||||||
if (HIO_LIKELY(file->task_req_method == HIO_HTTP_GET))
|
if (HIO_LIKELY(file->task_req_method == HIO_HTTP_GET))
|
||||||
{
|
{
|
||||||
if (file->etag_match)
|
if (file->etag_match)
|
||||||
{
|
{
|
||||||
status_code = HIO_HTTP_STATUS_NOT_MODIFIED;
|
status_code = HIO_HTTP_STATUS_NOT_MODIFIED;
|
||||||
goto done_with_status_code;
|
goto oops_with_status_code;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* normal full transfer */
|
/* normal full transfer */
|
||||||
@ -743,7 +743,7 @@ static int bind_task_to_peer (file_t* file, hio_htre_t* req, const hio_bch_t* fi
|
|||||||
{
|
{
|
||||||
if (file_send_header_to_client(file, HIO_HTTP_STATUS_OK, 0, actual_mime_type) <= -1) goto oops;
|
if (file_send_header_to_client(file, HIO_HTTP_STATUS_OK, 0, actual_mime_type) <= -1) goto oops;
|
||||||
/* no content must be transmitted for HEAD despite Content-Length in the header. */
|
/* no content must be transmitted for HEAD despite Content-Length in the header. */
|
||||||
goto done_with_status_code_2;
|
goto oops_with_status_code_2;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -753,10 +753,10 @@ static int bind_task_to_peer (file_t* file, hio_htre_t* req, const hio_bch_t* fi
|
|||||||
if (file->options & HIO_SVC_HTTS_FILE_READ_ONLY)
|
if (file->options & HIO_SVC_HTTS_FILE_READ_ONLY)
|
||||||
{
|
{
|
||||||
status_code = HIO_HTTP_STATUS_METHOD_NOT_ALLOWED;
|
status_code = HIO_HTTP_STATUS_METHOD_NOT_ALLOWED;
|
||||||
goto done_with_status_code;
|
goto oops_with_status_code;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (open_peer_with_mode(file, file_path, O_WRONLY | O_TRUNC | O_CREAT, &status_code, HIO_NULL) <= -1) goto done_with_status_code;
|
if (open_peer_with_mode(file, file_path, O_WRONLY | O_TRUNC | O_CREAT, &status_code, HIO_NULL) <= -1) goto oops_with_status_code;
|
||||||
|
|
||||||
/* the client input must be written to the peer side */
|
/* the client input must be written to the peer side */
|
||||||
file_mark_over (file, FILE_OVER_READ_FROM_PEER);
|
file_mark_over (file, FILE_OVER_READ_FROM_PEER);
|
||||||
@ -766,7 +766,7 @@ static int bind_task_to_peer (file_t* file, hio_htre_t* req, const hio_bch_t* fi
|
|||||||
if (file->options & HIO_SVC_HTTS_FILE_READ_ONLY)
|
if (file->options & HIO_SVC_HTTS_FILE_READ_ONLY)
|
||||||
{
|
{
|
||||||
status_code = HIO_HTTP_STATUS_METHOD_NOT_ALLOWED;
|
status_code = HIO_HTTP_STATUS_METHOD_NOT_ALLOWED;
|
||||||
goto done_with_status_code;
|
goto oops_with_status_code;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (unlink(file_path) <= -1)
|
if (unlink(file_path) <= -1)
|
||||||
@ -774,25 +774,28 @@ static int bind_task_to_peer (file_t* file, hio_htre_t* req, const hio_bch_t* fi
|
|||||||
if (errno != EISDIR || (errno == EISDIR && rmdir(file_path) <= -1))
|
if (errno != EISDIR || (errno == EISDIR && rmdir(file_path) <= -1))
|
||||||
{
|
{
|
||||||
status_code = ERRNO_TO_STATUS_CODE(errno);
|
status_code = ERRNO_TO_STATUS_CODE(errno);
|
||||||
goto done_with_status_code;
|
goto oops_with_status_code;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
status_code = HIO_HTTP_STATUS_OK;
|
status_code = HIO_HTTP_STATUS_OK;
|
||||||
goto done_with_status_code;
|
goto oops_with_status_code;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
status_code = HIO_HTTP_STATUS_METHOD_NOT_ALLOWED;
|
status_code = HIO_HTTP_STATUS_METHOD_NOT_ALLOWED;
|
||||||
done_with_status_code:
|
goto oops_with_status_code;
|
||||||
if (hio_svc_htts_task_sendfinalres(file, status_code, HIO_NULL, HIO_NULL, 0) <= -1) goto oops;
|
|
||||||
done_with_status_code_2:
|
|
||||||
file_mark_over (file, FILE_OVER_READ_FROM_PEER | FILE_OVER_WRITE_TO_PEER);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
HIO_SVC_HTTS_TASK_RCUP (file); /* for file->peer opened */
|
HIO_SVC_HTTS_TASK_RCUP (file); /* for file->peer opened */
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
|
||||||
|
/* the task can be terminated because the requested job has been
|
||||||
|
* completed or it can't proceed for various reasons */
|
||||||
|
oops_with_status_code:
|
||||||
|
hio_svc_htts_task_sendfinalres(file, status_code, HIO_NULL, HIO_NULL, 0);
|
||||||
|
oops_with_status_code_2:
|
||||||
|
file_mark_over (file, FILE_OVER_READ_FROM_PEER | FILE_OVER_WRITE_TO_PEER);
|
||||||
oops:
|
oops:
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -820,6 +823,7 @@ static void unbind_task_from_peer (file_t* file, int rcdown)
|
|||||||
{
|
{
|
||||||
while (n > 0)
|
while (n > 0)
|
||||||
{
|
{
|
||||||
|
HIO_DEBUG1(hio, "RCDOWN.... %d\n", n);
|
||||||
n--;
|
n--;
|
||||||
HIO_SVC_HTTS_TASK_RCDOWN((hio_svc_htts_task_t*)file);
|
HIO_SVC_HTTS_TASK_RCDOWN((hio_svc_htts_task_t*)file);
|
||||||
}
|
}
|
||||||
@ -881,6 +885,7 @@ int hio_svc_htts_dofile (hio_svc_htts_t* htts, hio_dev_sck_t* csck, hio_htre_t*
|
|||||||
|
|
||||||
file = (file_t*)hio_svc_htts_task_make(htts, HIO_SIZEOF(*file), file_on_kill, req, csck);
|
file = (file_t*)hio_svc_htts_task_make(htts, HIO_SIZEOF(*file), file_on_kill, req, csck);
|
||||||
if (HIO_UNLIKELY(!file)) goto oops;
|
if (HIO_UNLIKELY(!file)) goto oops;
|
||||||
|
HIO_SVC_HTTS_TASK_RCUP (file); /* for temporary protection */
|
||||||
|
|
||||||
file->on_kill = on_kill;
|
file->on_kill = on_kill;
|
||||||
file->options = options;
|
file->options = options;
|
||||||
@ -889,7 +894,7 @@ int hio_svc_htts_dofile (hio_svc_htts_t* htts, hio_dev_sck_t* csck, hio_htre_t*
|
|||||||
file->peer_tmridx = HIO_TMRIDX_INVALID;
|
file->peer_tmridx = HIO_TMRIDX_INVALID;
|
||||||
file->peer = -1;
|
file->peer = -1;
|
||||||
|
|
||||||
bind_task_to_client (file, csck);
|
bind_task_to_client (file, csck); /* the file task's reference count is incremented */
|
||||||
|
|
||||||
if (hio_svc_htts_task_handleexpect100(file) <= -1) goto oops;
|
if (hio_svc_htts_task_handleexpect100(file) <= -1) goto oops;
|
||||||
if (setup_for_content_length(file, req) <= -1) goto oops;
|
if (setup_for_content_length(file, req) <= -1) goto oops;
|
||||||
@ -901,11 +906,16 @@ int hio_svc_htts_dofile (hio_svc_htts_t* htts, hio_dev_sck_t* csck, hio_htre_t*
|
|||||||
hio_freemem (hio, actual_file);
|
hio_freemem (hio, actual_file);
|
||||||
|
|
||||||
HIO_SVC_HTTS_TASKL_APPEND_TASK (&htts->task, (hio_svc_htts_task_t*)file);
|
HIO_SVC_HTTS_TASKL_APPEND_TASK (&htts->task, (hio_svc_htts_task_t*)file);
|
||||||
|
HIO_SVC_HTTS_TASK_RCDOWN (file);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
oops:
|
oops:
|
||||||
HIO_DEBUG2 (hio, "HTTS(%p) - file(c=%d) failure\n", htts, csck->hnd);
|
HIO_DEBUG2 (hio, "HTTS(%p) - file(c=%d) failure\n", htts, csck->hnd);
|
||||||
if (file) file_halt_participating_devices (file);
|
if (file)
|
||||||
|
{
|
||||||
|
file_halt_participating_devices (file);
|
||||||
|
HIO_SVC_HTTS_TASK_RCDOWN (file);
|
||||||
|
}
|
||||||
if (actual_file) hio_freemem (hio, actual_file);
|
if (actual_file) hio_freemem (hio, actual_file);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -616,7 +616,7 @@ oops:
|
|||||||
void hio_svc_htts_stop (hio_svc_htts_t* htts)
|
void hio_svc_htts_stop (hio_svc_htts_t* htts)
|
||||||
{
|
{
|
||||||
hio_t* hio = htts->hio;
|
hio_t* hio = htts->hio;
|
||||||
hio_oow_t i;
|
hio_oow_t i, ntasks = 0;
|
||||||
|
|
||||||
HIO_DEBUG1 (hio, "HTTS - STOPPING SERVICE %p\n", htts);
|
HIO_DEBUG1 (hio, "HTTS - STOPPING SERVICE %p\n", htts);
|
||||||
|
|
||||||
@ -645,6 +645,7 @@ void hio_svc_htts_stop (hio_svc_htts_t* htts)
|
|||||||
{
|
{
|
||||||
hio_svc_htts_task_t* task = HIO_SVC_HTTS_TASKL_FIRST_TASK(&htts->task);
|
hio_svc_htts_task_t* task = HIO_SVC_HTTS_TASKL_FIRST_TASK(&htts->task);
|
||||||
hio_svc_htts_task_kill (task);
|
hio_svc_htts_task_kill (task);
|
||||||
|
ntasks++;
|
||||||
}
|
}
|
||||||
|
|
||||||
HIO_SVCL_UNLINK_SVC (htts);
|
HIO_SVCL_UNLINK_SVC (htts);
|
||||||
@ -657,7 +658,8 @@ void hio_svc_htts_stop (hio_svc_htts_t* htts)
|
|||||||
if (htts->becbuf) hio_becs_close (htts->becbuf);
|
if (htts->becbuf) hio_becs_close (htts->becbuf);
|
||||||
hio_freemem (hio, htts);
|
hio_freemem (hio, htts);
|
||||||
|
|
||||||
HIO_DEBUG1 (hio, "HTTS - STOPPED SERVICE %p\n", htts);
|
/* it's not a good sign if the number of remaining tasks is greater than 0 */
|
||||||
|
HIO_DEBUG2 (hio, "HTTS - STOPPED SERVICE %p - killed %zu remaining tasks\n", htts, ntasks);
|
||||||
}
|
}
|
||||||
|
|
||||||
void* hio_svc_htts_getxtn (hio_svc_htts_t* htts)
|
void* hio_svc_htts_getxtn (hio_svc_htts_t* htts)
|
||||||
|
Loading…
Reference in New Issue
Block a user