enhanced hio_dev_kill() by protecting against duplicate calls on the same device

This commit is contained in:
hyung-hwan 2022-09-13 14:33:49 +00:00
parent 7a35f9ae4c
commit e03b9bd9a9
5 changed files with 48 additions and 8 deletions

View File

@ -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;

View File

@ -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,

View File

@ -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);
}
}

View File

@ -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;

View File

@ -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))
{