From c7e989518fa37e45907cb95fddd8393dc2148b44 Mon Sep 17 00:00:00 2001 From: hyung-hwan Date: Thu, 16 Nov 2023 12:29:54 +0900 Subject: [PATCH] fixed the early task termination issue in http-file.c --- lib/hio-http.h | 2 ++ lib/hio.c | 18 +++++++++++++----- lib/htrd.c | 4 +--- lib/http-file.c | 42 ++++++++++++++++++++++++++---------------- lib/http-svr.c | 6 ++++-- 5 files changed, 46 insertions(+), 26 deletions(-) diff --git a/lib/hio-http.h b/lib/hio-http.h index ba58598..f2c520c 100644 --- a/lib/hio-http.h +++ b/lib/hio-http.h @@ -119,6 +119,8 @@ struct hio_svc_htts_task_t 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_RCDOWN(task_var) do { \ diff --git a/lib/hio.c b/lib/hio.c index bbf89b2..584f632 100644 --- a/lib/hio.c +++ b/lib/hio.c @@ -159,6 +159,7 @@ void hio_fini (hio_t* hio) hio_dev_t* dev, * next_dev; hio_dev_t diehard; hio_oow_t i; + hio_oow_t nactdevs = 0, nhltdevs = 0, nzmbdevs = 0, ndieharddevs = 0; /* statistics */ hio->_fini_in_progress = 1; @@ -204,12 +205,14 @@ void hio_fini (hio_t* hio) while (!HIO_DEVL_IS_EMPTY(&hio->actdev)) { hio_dev_kill (HIO_DEVL_FIRST_DEV(&hio->actdev)); + nactdevs++; } /* kill all halted devices */ while (!HIO_DEVL_IS_EMPTY(&hio->hltdev)) { hio_dev_kill (HIO_DEVL_FIRST_DEV(&hio->hltdev)); + nhltdevs++; } /* clean up all zombie devices */ @@ -219,7 +222,7 @@ void hio_fini (hio_t* hio) kill_and_free_device (dev, 1); 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; /* remove the device from the zombie device list */ @@ -231,7 +234,11 @@ void hio_fini (hio_t* hio) 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)) @@ -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_DEVL_UNLINK_DEV (dev); kill_and_free_device (dev, 2); + ndieharddevs++; } /* purge scheduled timer jobs and kill the timer */ @@ -2019,7 +2027,7 @@ void hio_gettime (hio_t* hio, hio_ntime_t* now) void* hio_allocmem (hio_t* hio, hio_oow_t size) { void* ptr; - ptr = HIO_MMGR_ALLOC (hio->_mmgr, size); + ptr = HIO_MMGR_ALLOC(hio->_mmgr, size); if (!ptr) hio_seterrnum (hio, HIO_ESYSMEM); return ptr; } @@ -2027,7 +2035,7 @@ void* hio_allocmem (hio_t* hio, hio_oow_t size) void* hio_callocmem (hio_t* hio, hio_oow_t size) { void* ptr; - ptr = HIO_MMGR_ALLOC (hio->_mmgr, size); + ptr = HIO_MMGR_ALLOC(hio->_mmgr, size); if (!ptr) hio_seterrnum (hio, HIO_ESYSMEM); else HIO_MEMSET (ptr, 0, size); return ptr; @@ -2035,7 +2043,7 @@ void* hio_callocmem (hio_t* hio, hio_oow_t size) void* hio_reallocmem (hio_t* hio, void* ptr, hio_oow_t size) { - ptr = HIO_MMGR_REALLOC (hio->_mmgr, ptr, size); + ptr = HIO_MMGR_REALLOC(hio->_mmgr, ptr, size); if (!ptr) hio_seterrnum (hio, HIO_ESYSMEM); return ptr; } diff --git a/lib/htrd.c b/lib/htrd.c index aeb32a1..2cfc23a 100644 --- a/lib/htrd.c +++ b/lib/htrd.c @@ -648,9 +648,7 @@ struct hdr_cbserter_ctx_t hio_oow_t vlen; }; -static hio_htb_pair_t* hdr_cbserter ( - hio_htb_t* htb, hio_htb_pair_t* pair, - void* kptr, hio_oow_t klen, void* ctx) +static hio_htb_pair_t* hdr_cbserter (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; diff --git a/lib/http-file.c b/lib/http-file.c index ce1cba7..fbda2f2 100644 --- a/lib/http-file.c +++ b/lib/http-file.c @@ -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; 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 (file->etag_match) { status_code = HIO_HTTP_STATUS_NOT_MODIFIED; - goto done_with_status_code; + goto oops_with_status_code; } /* 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; /* 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; } @@ -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) { 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 */ 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) { status_code = HIO_HTTP_STATUS_METHOD_NOT_ALLOWED; - goto done_with_status_code; + goto oops_with_status_code; } 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)) { status_code = ERRNO_TO_STATUS_CODE(errno); - goto done_with_status_code; + goto oops_with_status_code; } } status_code = HIO_HTTP_STATUS_OK; - goto done_with_status_code; + goto oops_with_status_code; default: status_code = HIO_HTTP_STATUS_METHOD_NOT_ALLOWED; - done_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; + goto oops_with_status_code; } HIO_SVC_HTTS_TASK_RCUP (file); /* for file->peer opened */ 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: return -1; } @@ -816,10 +819,11 @@ static void unbind_task_from_peer (file_t* file, int rcdown) n++; } - if (rcdown) + if (rcdown) { while (n > 0) { +HIO_DEBUG1(hio, "RCDOWN.... %d\n", n); n--; 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); if (HIO_UNLIKELY(!file)) goto oops; + HIO_SVC_HTTS_TASK_RCUP (file); /* for temporary protection */ file->on_kill = on_kill; 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 = -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 (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_SVC_HTTS_TASKL_APPEND_TASK (&htts->task, (hio_svc_htts_task_t*)file); + HIO_SVC_HTTS_TASK_RCDOWN (file); return 0; oops: 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); return -1; } diff --git a/lib/http-svr.c b/lib/http-svr.c index 6417e94..a1ad812 100644 --- a/lib/http-svr.c +++ b/lib/http-svr.c @@ -616,7 +616,7 @@ oops: void hio_svc_htts_stop (hio_svc_htts_t* htts) { hio_t* hio = htts->hio; - hio_oow_t i; + hio_oow_t i, ntasks = 0; 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_kill (task); + ntasks++; } 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); 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)