fixed the cgi task counting bug

This commit is contained in:
hyung-hwan 2023-11-18 22:23:08 +09:00
parent cc5c027277
commit 52829974ec
5 changed files with 59 additions and 29 deletions

View File

@ -427,7 +427,7 @@ int webs_start (hio_t* hio, const arg_info_t* ai)
{ {
hio_oow_t ov; hio_oow_t ov;
ov = 100; ov = 200;
hio_svc_htts_setoption (webs, HIO_SVC_HTTS_TASK_CGI_MAX, &ov); hio_svc_htts_setoption (webs, HIO_SVC_HTTS_TASK_CGI_MAX, &ov);
} }

View File

@ -46,7 +46,7 @@ static HIO_INLINE void hio_spl_init (hio_spl_t* spl) { *spl = HIO_SPL_INIT; }
#if defined(HIO_HAVE_INLINE) #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 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); } static HIO_INLINE void hio_spl_unlock (hio_spl_t* spl) { __sync_lock_release(spl); }
#else #else
# define hio_spl_trylock(spl) (!__sync_lock_test_and_set(spl, 1)) # define hio_spl_trylock(spl) (!__sync_lock_test_and_set(spl, 1))

View File

@ -63,6 +63,7 @@ struct cgi_t
unsigned int over: 4; /* must be large enough to accomodate CGI_OVER_ALL */ unsigned int over: 4; /* must be large enough to accomodate CGI_OVER_ALL */
unsigned int client_htrd_recbs_changed: 1; 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_read_t client_org_on_read;
hio_dev_sck_on_write_t client_org_on_write; 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) 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; int ok;
do 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); ok = HCL_ATOMIC_CMP_XCHG(&htts->stat.ntask_cgis, &ntask_cgis, ntask_cgis + 1);
} }
while (!ok); 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 #endif
return 0; return 0;
} }
static void dec_ntask_cgis (hio_svc_htts_t* htts) 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; int ok;
do 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); ok = HCL_ATOMIC_CMP_XCHG(&htts->stat.ntask_cgis, &ntask_cgis, ntask_cgis - 1);
} }
while (!ok); while (!ok);
#else
htts->stat.ntask_cgis--;
#endif #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 */ 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); 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); hio_svc_htts_cli_t* cli = hio_dev_sck_getxtn(csck);
cgi_t* cgi = HIO_NULL; cgi_t* cgi = HIO_NULL;
int n, status_code = HIO_HTTP_STATUS_INTERNAL_SERVER_ERROR; 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 */ /* ensure that you call this function before any contents is received */
HIO_ASSERT (hio, hio_htre_getcontentlen(req) == 0); 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; status_code = HIO_HTTP_STATUS_SERVICE_UNAVAILABLE;
goto oops; goto oops;
} }
cgi->ntask_cgis_inced = 1;
cgi->options = options; cgi->options = options;
bind_task_to_client (cgi, csck); 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); HIO_SVC_HTTS_TASK_RCDOWN((hio_svc_htts_task_t*)cgi);
/* set the on_kill callback only if this function can return success. /* 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; cgi->on_kill = on_kill;
return 0; return 0;

View File

@ -28,6 +28,7 @@
#include <hio-http.h> #include <hio-http.h>
#include <hio-htrd.h> #include <hio-htrd.h>
#include <hio-sck.h> #include <hio-sck.h>
#include <hio-spl.h>
#include "hio-prv.h" #include "hio-prv.h"
struct hio_svc_htts_cli_t struct hio_svc_htts_cli_t
@ -89,6 +90,10 @@ struct hio_svc_htts_t
{ {
hio_ooi_t ntasks; hio_ooi_t ntasks;
hio_ooi_t ntask_cgis; 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; } stat;
}; };

View File

@ -42,7 +42,17 @@ static void client_on_disconnect (hio_dev_sck_t* sck);
static int inc_ntasks (hio_svc_htts_t* htts) 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; int ok;
do 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); ok = HCL_ATOMIC_CMP_XCHG(&htts->stat.ntasks, &ntasks, ntasks + 1);
} }
while (!ok); 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 #endif
return 0; return 0;
} }
static void dec_ntasks (hio_svc_htts_t* htts) 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; int ok;
do 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); ok = HCL_ATOMIC_CMP_XCHG(&htts->stat.ntasks, &ntasks, ntasks - 1);
} }
while (!ok); while (!ok);
#else
htts->stat.ntasks--;
#endif #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; return htts;
oops: oops:
@ -729,7 +741,8 @@ int hio_svc_htts_getoption (hio_svc_htts_t* htts, hio_svc_htts_option_t id, void
return 0; return 0;
einval: 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) int hio_svc_htts_setoption (hio_svc_htts_t* htts, hio_svc_htts_option_t id, const void* value)