diff --git a/bin/webs.c b/bin/webs.c index 03a97c6..252f8ef 100644 --- a/bin/webs.c +++ b/bin/webs.c @@ -427,7 +427,7 @@ int webs_start (hio_t* hio, const arg_info_t* ai) { hio_oow_t ov; - ov = 100; + ov = 200; hio_svc_htts_setoption (webs, HIO_SVC_HTTS_TASK_CGI_MAX, &ov); } diff --git a/lib/hio-spl.h b/lib/hio-spl.h index 6c49a72..3deaa39 100644 --- a/lib/hio-spl.h +++ b/lib/hio-spl.h @@ -46,7 +46,7 @@ static HIO_INLINE void hio_spl_init (hio_spl_t* spl) { *spl = HIO_SPL_INIT; } #if defined(HIO_HAVE_INLINE) static HIO_INLINE int hio_spl_trylock (hio_spl_t* spl) { return !__sync_lock_test_and_set(spl, 1); } -static HIO_INLINE void hio_spl_lock (hio_spl_t* spl) { do {} while(__sync_lock_test_and_set(spl, 1)); } +static HIO_INLINE void hio_spl_lock (hio_spl_t* spl) { while(__sync_lock_test_and_set(spl, 1)); } static HIO_INLINE void hio_spl_unlock (hio_spl_t* spl) { __sync_lock_release(spl); } #else # define hio_spl_trylock(spl) (!__sync_lock_test_and_set(spl, 1)) diff --git a/lib/http-cgi.c b/lib/http-cgi.c index 3b77ba2..f90796b 100644 --- a/lib/http-cgi.c +++ b/lib/http-cgi.c @@ -63,6 +63,7 @@ struct cgi_t unsigned int over: 4; /* must be large enough to accomodate CGI_OVER_ALL */ unsigned int client_htrd_recbs_changed: 1; + unsigned int ntask_cgis_inced: 1; hio_dev_sck_on_read_t client_org_on_read; hio_dev_sck_on_write_t client_org_on_write; @@ -86,7 +87,17 @@ static void unbind_task_from_peer (cgi_t* cgi, int rcdown); static int inc_ntask_cgis (hio_svc_htts_t* htts) { -#if defined(HCL_ATOMIC_LOAD) && defined(HCL_ATOMIC_CMP_XCHG) +#if !(defined(HCL_ATOMIC_LOAD) && defined(HCL_ATOMIC_CMP_XCHG)) + hio_spl_lock (&htts->stat.spl_ntask_cgis); + if (htts->stat.ntask_cgis >= htts->option.task_cgi_max) + { + hio_spl_unlock (&htts->stat.spl_ntask_cgis); + hio_seterrbfmt (htts->hio, HIO_ENOCAPA, "too many cgi tasks"); + return -1; + } + htts->stat.ntask_cgis++; + hio_spl_unlock (&htts->stat.spl_ntask_cgis); +#else int ok; do { @@ -100,20 +111,17 @@ static int inc_ntask_cgis (hio_svc_htts_t* htts) ok = HCL_ATOMIC_CMP_XCHG(&htts->stat.ntask_cgis, &ntask_cgis, ntask_cgis + 1); } while (!ok); -#else - if (htts->stat.ntask_cgis >= htts->option.task_cgi_max) - { - hio_seterrbfmt (htts->hio, HIO_ENOCAPA, "too many cgi tasks"); - return -1; - } - htts->stat.ntask_cgis++; #endif return 0; } static void dec_ntask_cgis (hio_svc_htts_t* htts) { -#if defined(HCL_ATOMIC_LOAD) && defined(HCL_ATOMIC_CMP_XCHG) +#if !(defined(HCL_ATOMIC_LOAD) && defined(HCL_ATOMIC_CMP_XCHG)) + hio_spl_lock (&htts->stat.spl_ntask_cgis); + htts->stat.ntask_cgis--; + hio_spl_unlock (&htts->stat.spl_ntask_cgis); +#else int ok; do { @@ -122,8 +130,6 @@ static void dec_ntask_cgis (hio_svc_htts_t* htts) ok = HCL_ATOMIC_CMP_XCHG(&htts->stat.ntask_cgis, &ntask_cgis, ntask_cgis - 1); } while (!ok); -#else - htts->stat.ntask_cgis--; #endif } @@ -243,7 +249,12 @@ static void cgi_on_kill (hio_svc_htts_task_t* task) } if (cgi->task_next) HIO_SVC_HTTS_TASKL_UNLINK_TASK (cgi); /* detach from the htts service only if it's attached */ - dec_ntask_cgis (cgi->htts); + + if (cgi->ntask_cgis_inced) + { + dec_ntask_cgis (cgi->htts); + cgi->ntask_cgis_inced = 0; + } HIO_DEBUG5 (hio, "HTTS(%p) - cgi(t=%p,c=%p[%d],p=%p) - killed the task\n", cgi->htts, cgi, cgi->task_client, (cgi->task_csck? cgi->task_csck->hnd: -1), cgi->peer); } @@ -992,7 +1003,7 @@ int hio_svc_htts_docgi (hio_svc_htts_t* htts, hio_dev_sck_t* csck, hio_htre_t* r hio_svc_htts_cli_t* cli = hio_dev_sck_getxtn(csck); cgi_t* cgi = HIO_NULL; int n, status_code = HIO_HTTP_STATUS_INTERNAL_SERVER_ERROR; - int bound_to_client = 0, bound_to_peer = 0; + int bound_to_client = 0, bound_to_peer = 0, ntask_cgi_inced = 0; /* ensure that you call this function before any contents is received */ HIO_ASSERT (hio, hio_htre_getcontentlen(req) == 0); @@ -1012,7 +1023,7 @@ int hio_svc_htts_docgi (hio_svc_htts_t* htts, hio_dev_sck_t* csck, hio_htre_t* r status_code = HIO_HTTP_STATUS_SERVICE_UNAVAILABLE; goto oops; } - + cgi->ntask_cgis_inced = 1; cgi->options = options; bind_task_to_client (cgi, csck); @@ -1035,7 +1046,8 @@ int hio_svc_htts_docgi (hio_svc_htts_t* htts, hio_dev_sck_t* csck, hio_htre_t* r HIO_SVC_HTTS_TASK_RCDOWN((hio_svc_htts_task_t*)cgi); /* set the on_kill callback only if this function can return success. - * the on_kill callback won't be executed if this function returns failure. */ + * the on_kill callback won't be executed if this function returns failure. + * however, the internal callback cgi_on_kill is still called */ cgi->on_kill = on_kill; return 0; diff --git a/lib/http-prv.h b/lib/http-prv.h index c94c040..6afd2b7 100644 --- a/lib/http-prv.h +++ b/lib/http-prv.h @@ -28,6 +28,7 @@ #include #include #include +#include #include "hio-prv.h" struct hio_svc_htts_cli_t @@ -89,6 +90,10 @@ struct hio_svc_htts_t { hio_ooi_t ntasks; hio_ooi_t ntask_cgis; + #if !(defined(HCL_ATOMIC_LOAD) && defined(HCL_ATOMIC_CMP_XCHG)) + hio_spl_t spl_ntasks; + hio_spl_t spl_ntask_cgis; + #endif } stat; }; diff --git a/lib/http-svr.c b/lib/http-svr.c index 5bc253f..1982598 100644 --- a/lib/http-svr.c +++ b/lib/http-svr.c @@ -42,7 +42,17 @@ static void client_on_disconnect (hio_dev_sck_t* sck); static int inc_ntasks (hio_svc_htts_t* htts) { -#if defined(HCL_ATOMIC_LOAD) && defined(HCL_ATOMIC_CMP_XCHG) +#if !(defined(HCL_ATOMIC_LOAD) && defined(HCL_ATOMIC_CMP_XCHG)) + hio_spl_lock (&htts->stat.spl_ntasks); + if (htts->stat.ntasks >= htts->option.task_max) + { + hio_spl_unlock (&htts->stat.spl_ntasks); + hio_seterrbfmt (htts->hio, HIO_ENOCAPA, "too many tasks"); + return -1; + } + htts->stat.ntasks++; + hio_spl_unlock (&htts->stat.spl_ntasks); +#else int ok; do { @@ -56,20 +66,17 @@ static int inc_ntasks (hio_svc_htts_t* htts) ok = HCL_ATOMIC_CMP_XCHG(&htts->stat.ntasks, &ntasks, ntasks + 1); } while (!ok); -#else - if (htts->stat.ntasks >= htts->option.task_max) - { - hio_seterrbfmt (htts->hio, HIO_ENOCAPA, "too many tasks"); - return -1; - } - htts->stat.ntasks++; #endif return 0; } static void dec_ntasks (hio_svc_htts_t* htts) { -#if defined(HCL_ATOMIC_LOAD) && defined(HCL_ATOMIC_CMP_XCHG) +#if !(defined(HCL_ATOMIC_LOAD) && defined(HCL_ATOMIC_CMP_XCHG)) + hio_spl_lock (&htts->stat.spl_ntasks); + htts->stat.ntasks--; + hio_spl_unlock (&htts->stat.spl_ntasks); +#else int ok; do { @@ -78,8 +85,6 @@ static void dec_ntasks (hio_svc_htts_t* htts) ok = HCL_ATOMIC_CMP_XCHG(&htts->stat.ntasks, &ntasks, ntasks - 1); } while (!ok); -#else - htts->stat.ntasks--; #endif } @@ -629,6 +634,13 @@ hio_svc_htts_t* hio_svc_htts_start (hio_t* hio, hio_oow_t xtnsize, hio_dev_sck_b } } + +#if !(defined(HCL_ATOMIC_LOAD) && defined(HCL_ATOMIC_CMP_XCHG)) + hio_spl_init (&htts->stat.spl_ntasks); + hio_spl_init (&htts->stat.spl_ntask_cgis); +#endif + + return htts; oops: @@ -729,7 +741,8 @@ int hio_svc_htts_getoption (hio_svc_htts_t* htts, hio_svc_htts_option_t id, void return 0; einval: - hio_seterrnum (htts->hio, HIO_EINVAL); + hio_seterrnum (htts->hio, HIO_EINVAL); + return -1; } int hio_svc_htts_setoption (hio_svc_htts_t* htts, hio_svc_htts_option_t id, const void* value)