From e03b9bd9a98289a17340f0f40a375365af5fe06f Mon Sep 17 00:00:00 2001 From: hyung-hwan Date: Tue, 13 Sep 2022 14:33:49 +0000 Subject: [PATCH] enhanced hio_dev_kill() by protecting against duplicate calls on the same device --- hio/lib/fcgi-cli.c | 29 ++++++++++++++++++++++++----- hio/lib/hio-http.h | 1 - hio/lib/hio.c | 23 ++++++++++++++++++++++- hio/lib/hio.h | 2 +- hio/lib/sck.c | 1 + 5 files changed, 48 insertions(+), 8 deletions(-) diff --git a/hio/lib/fcgi-cli.c b/hio/lib/fcgi-cli.c index bf572b9..de854ce 100644 --- a/hio/lib/fcgi-cli.c +++ b/hio/lib/fcgi-cli.c @@ -118,9 +118,17 @@ static void sck_on_disconnect (hio_dev_sck_t* sck) fcgic_sck_xtn_t* sck_xtn = hio_dev_sck_getxtn(sck); hio_svc_fcgic_conn_t* conn = sck_xtn->conn; + if (conn) + { /* TODO: arrange to create it again if the server is not closing... */ /* if (.... ) */ - make_connection_socket(conn); /* don't care about failure for now */ +printf ("DISCONNECT SOCKET .................. %p\n", sck); + if (sck->hio->stopreq == HIO_STOPREQ_NONE) + { + /* this may create a busy loop if the connection attempt fails repeatedly */ + make_connection_socket(conn); /* don't care about failure for now */ + } + } } @@ -189,15 +197,20 @@ static int make_connection_socket (hio_svc_fcgic_conn_t* conn) if (hio_dev_sck_connect(sck, &ci) <= -1) { -/* TODO: check if this tirggers on_disconnecT???/ */ - hio_dev_sck_kill (sck); + /* immediate failure */ + sck_xtn->conn = HIO_NULL; /* disassociate the socket from the fcgi connection object */ + hio_dev_sck_halt (sck); return -1; } + printf ("MAKING CONNECTION %p %p\n", conn->dev, sck); + if (conn->dev != HIO_NULL) { /* TODO: is this necessary???? */ - hio_dev_sck_kill (conn->dev); + sck_xtn = hio_dev_sck_getxtn(conn->dev); + sck_xtn->conn = HIO_NULL; + hio_dev_sck_halt (conn->dev); conn->dev = HIO_NULL; } @@ -251,7 +264,13 @@ static void free_connections (hio_svc_fcgic_t* fcgic) while (conn) { next = conn->next; - if (conn->dev) hio_dev_sck_kill (conn->dev); + if (conn->dev) + { + struct fcgic_sck_xtn_t* sck_xtn; + sck_xtn = hio_dev_sck_getxtn(conn->dev); + sck_xtn->conn = HIO_NULL; + hio_dev_sck_halt (conn->dev); + } hio_freemem (hio, conn->sess.ptr); hio_freemem (hio, conn); conn = next; diff --git a/hio/lib/hio-http.h b/hio/lib/hio-http.h index 55cd088..bba2866 100644 --- a/hio/lib/hio-http.h +++ b/hio/lib/hio-http.h @@ -312,7 +312,6 @@ HIO_EXPORT int hio_svc_htts_dofcgi ( const hio_skad_t* fcgis_addr ); - HIO_EXPORT int hio_svc_htts_dofile ( hio_svc_htts_t* htts, hio_dev_sck_t* csck, diff --git a/hio/lib/hio.c b/hio/lib/hio.c index 8a3fcda..3a7b063 100644 --- a/hio/lib/hio.c +++ b/hio/lib/hio.c @@ -1038,6 +1038,7 @@ hio_dev_t* hio_dev_make (hio_t* hio, hio_oow_t dev_size, hio_dev_mth_t* dev_mth, /* and place the new device object at the back of the active device list */ HIO_DEVL_APPEND_DEV (&hio->actdev, dev); dev->dev_cap |= HIO_DEV_CAP_ACTIVE; + HIO_DEBUG1 (hio, "MIO - Set ACTIVE on device %p\n", dev); return dev; @@ -1080,18 +1081,23 @@ static int kill_and_free_device (hio_dev_t* dev, int force) HIO_ASSERT (hio, !(dev->dev_cap & HIO_DEV_CAP_ACTIVE)); HIO_ASSERT (hio, !(dev->dev_cap & HIO_DEV_CAP_HALTED)); + HIO_DEBUG1 (hio, "MIO - Calling kill method on device %p\n", dev); if (dev->dev_mth->kill(dev, force) <= -1) { + HIO_DEBUG1 (hio, "MIO - Failure by kill method on device %p\n", dev); + if (force >= 2) goto free_device; if (!(dev->dev_cap & HIO_DEV_CAP_ZOMBIE)) { + HIO_DEBUG1 (hio, "MIO - Set ZOMBIE on device %p for kill method failure\n", dev); HIO_DEVL_APPEND_DEV (&hio->zmbdev, dev); dev->dev_cap |= HIO_DEV_CAP_ZOMBIE; } return -1; } + HIO_DEBUG1 (hio, "MIO - Success by kill method on device %p\n", dev); free_device: if (dev->dev_cap & HIO_DEV_CAP_ZOMBIE) @@ -1099,8 +1105,10 @@ free_device: /* detach it from the zombie device list */ HIO_DEVL_UNLINK_DEV (dev); dev->dev_cap &= ~HIO_DEV_CAP_ZOMBIE; + HIO_DEBUG1 (hio, "MIO - Unset ZOMBIE on device %p\n", dev); } + HIO_DEBUG1 (hio, "MIO - Freeing device %p\n", dev); hio_freemem (hio, dev); return 0; } @@ -1161,6 +1169,15 @@ void hio_dev_kill (hio_dev_t* dev) goto kill_device; } + if (!(dev->dev_cap & (HIO_DEV_CAP_HALTED | HIO_DEV_CAP_ACTIVE))) + { + /* neither HALTED nor ACTIVE set on the device. + * a call to this function is probably made again from a + * disconnect callback executed in kill_and_free_device() below ... */ + HIO_DEBUG1 (hio, "MIO - Duplicate kill on device %p\n", dev); + return; + } + if (dev->rtmridx != HIO_TMRIDX_INVALID) { hio_deltmrjob (hio, dev->rtmridx); @@ -1185,12 +1202,14 @@ void hio_dev_kill (hio_dev_t* dev) * unlink it from the halted device list */ HIO_DEVL_UNLINK_DEV (dev); dev->dev_cap &= ~HIO_DEV_CAP_HALTED; + HIO_DEBUG1 (hio, "MIO - Unset HALTED on device %p\n", dev); } else { HIO_ASSERT (hio, dev->dev_cap & HIO_DEV_CAP_ACTIVE); HIO_DEVL_UNLINK_DEV (dev); dev->dev_cap &= ~HIO_DEV_CAP_ACTIVE; + HIO_DEBUG1 (hio, "MIO - Unset ACTIVE on device %p\n", dev); } hio_dev_watch (dev, HIO_DEV_WATCH_STOP, 0); @@ -1223,15 +1242,17 @@ void hio_dev_halt (hio_dev_t* dev) if (dev->dev_cap & HIO_DEV_CAP_ACTIVE) { - HIO_DEBUG1 (hio, "MIO - HALTING DEVICE %p\n", dev); + HIO_DEBUG1 (hio, "MIO - Halting device %p\n", dev); /* delink the device object from the active device list */ HIO_DEVL_UNLINK_DEV (dev); dev->dev_cap &= ~HIO_DEV_CAP_ACTIVE; + HIO_DEBUG1 (hio, "MIO - Unset ACTIVE on device %p\n", dev); /* place it at the back of the halted device list */ HIO_DEVL_APPEND_DEV (&hio->hltdev, dev); dev->dev_cap |= HIO_DEV_CAP_HALTED; + HIO_DEBUG1 (hio, "MIO - Set HALTED on device %p\n", dev); } } diff --git a/hio/lib/hio.h b/hio/lib/hio.h index 1f46bb5..27682b3 100644 --- a/hio/lib/hio.h +++ b/hio/lib/hio.h @@ -436,7 +436,7 @@ enum hio_dev_cap_t HIO_DEV_CAP_RENEW_REQUIRED = ((hio_bitmask_t)1 << 18), HIO_DEV_CAP_WATCH_STARTED = ((hio_bitmask_t)1 << 19), HIO_DEV_CAP_WATCH_SUSPENDED = ((hio_bitmask_t)1 << 20), - HIO_DEV_CAP_WATCH_REREG_REQUIRED = ((hio_bitmask_t)1 << 21), + HIO_DEV_CAP_WATCH_REREG_REQUIRED = ((hio_bitmask_t)1 << 21) }; typedef enum hio_dev_cap_t hio_dev_cap_t; diff --git a/hio/lib/sck.c b/hio/lib/sck.c index 0841c7f..f9727d7 100644 --- a/hio/lib/sck.c +++ b/hio/lib/sck.c @@ -490,6 +490,7 @@ static int dev_sck_kill (hio_dev_t* dev, int force) hio_t* hio = dev->hio; hio_dev_sck_t* rdev = (hio_dev_sck_t*)dev; + HIO_DEBUG1 (hio, "SCK(%p) - being killed\n", rdev); #if 0 if (IS_STREAM(rdev)) {