fixed the premature EOF reporting caused by a file descriptor added without intention of input/output watching. as EPOLLHUP is always waited for, it caused early EOF reporting
This commit is contained in:
		| @ -1045,7 +1045,7 @@ int mio_dev_watch (mio_dev_t* dev, mio_dev_watch_cmd_t cmd, int events) | ||||
| 	if (dev->dev_cap & MIO_DEV_CAP_VIRTUAL) return 0; | ||||
|  | ||||
| 	/*ev.data.ptr = dev;*/ | ||||
| 	dev_cap = dev->dev_cap & ~(DEV_CAP_ALL_WATCHED); | ||||
| 	dev_cap = dev->dev_cap & ~(DEV_CAP_ALL_WATCHED | MIO_DEV_CAP_WATCH_SUSPENDED); /* UGLY to use MIO_DEV_CAP_WATCH_SUSPENDED here */ | ||||
|  | ||||
| 	switch (cmd) | ||||
| 	{ | ||||
| @ -1116,7 +1116,8 @@ int mio_dev_watch (mio_dev_t* dev, mio_dev_watch_cmd_t cmd, int events) | ||||
| 		if (mio_sys_ctrlmux(mio, mux_cmd, dev, dev_cap) <= -1) return -1; | ||||
| 	} | ||||
|  | ||||
| 	dev->dev_cap = dev_cap; | ||||
| 	/* UGLY. MIO_DEV_CAP_WATCH_SUSPENDED may be set/unset by mio_sys_ctrlmux. I need this to reflect it */ | ||||
| 	dev->dev_cap = dev_cap | (dev->dev_cap & MIO_DEV_CAP_WATCH_SUSPENDED); | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
|  | ||||
| @ -390,7 +390,8 @@ enum mio_dev_cap_t | ||||
| 	MIO_DEV_CAP_HALTED          = (1 << 16), | ||||
| 	MIO_DEV_CAP_ZOMBIE          = (1 << 17), | ||||
| 	MIO_DEV_CAP_RENEW_REQUIRED  = (1 << 18), | ||||
| 	MIO_DEV_CAP_WATCH_STARTED   = (1 << 19) | ||||
| 	MIO_DEV_CAP_WATCH_STARTED   = (1 << 19), | ||||
| 	MIO_DEV_CAP_WATCH_SUSPENDED = (1 << 20) | ||||
| }; | ||||
| typedef enum mio_dev_cap_t mio_dev_cap_t; | ||||
|  | ||||
|  | ||||
| @ -186,7 +186,7 @@ int mio_sys_ctrlmux (mio_t* mio, mio_sys_mux_cmd_t cmd, mio_dev_t* dev, int dev_ | ||||
|  | ||||
| 			MIO_ASSERT (mio, mux->pd.dptr[idx] == dev); | ||||
| 			mux->pd.pfd[idx].events = events; | ||||
| 			 | ||||
|  | ||||
| 			return 0; | ||||
| 		} | ||||
|  | ||||
| @ -235,26 +235,85 @@ int mio_sys_ctrlmux (mio_t* mio, mio_sys_mux_cmd_t cmd, mio_dev_t* dev, int dev_ | ||||
| 	} | ||||
| #elif defined(USE_EPOLL) | ||||
| 	mio_sys_mux_t* mux = &mio->sysdep->mux; | ||||
| 	static int epoll_cmd[] = { EPOLL_CTL_ADD, EPOLL_CTL_MOD, EPOLL_CTL_DEL }; | ||||
| 	struct epoll_event ev; | ||||
| 	mio_syshnd_t hnd; | ||||
| 	mio_uint32_t events; | ||||
| 	int x; | ||||
|  | ||||
| 	MIO_ASSERT (mio, mio == dev->mio); | ||||
| 	hnd = dev->dev_mth->getsyshnd(dev); | ||||
|  | ||||
| 	ev.data.ptr = dev; | ||||
| 	ev.events = EPOLLHUP | EPOLLERR /*| EPOLLET*/; | ||||
|  | ||||
| 	events = 0; | ||||
| 	if (dev_cap & MIO_DEV_CAP_IN_WATCHED)  | ||||
| 	{ | ||||
| 		ev.events |= EPOLLIN; | ||||
| 		events |= EPOLLIN; | ||||
| 	#if defined(EPOLLRDHUP) | ||||
| 		ev.events |= EPOLLRDHUP; | ||||
| 		events |= EPOLLRDHUP; | ||||
| 	#endif | ||||
| 		if (dev_cap & MIO_DEV_CAP_PRI_WATCHED) ev.events |= EPOLLPRI; | ||||
| 		if (dev_cap & MIO_DEV_CAP_PRI_WATCHED) events |= EPOLLPRI; | ||||
| 	} | ||||
| 	if (dev_cap & MIO_DEV_CAP_OUT_WATCHED) events |= EPOLLOUT; | ||||
|  | ||||
| 	ev.events = events | EPOLLHUP | EPOLLERR /*| EPOLLET*/; | ||||
| 	ev.data.ptr = dev; | ||||
|  | ||||
| 	switch (cmd) | ||||
| 	{ | ||||
| 		case MIO_SYS_MUX_CMD_INSERT: | ||||
| 			if (MIO_UNLIKELY(dev->dev_cap & MIO_DEV_CAP_WATCH_SUSPENDED)) | ||||
| 			{ | ||||
| 				mio_seterrnum (mio, MIO_EEXIST); | ||||
| 				return -1; | ||||
| 			} | ||||
|  | ||||
| 			x = epoll_ctl(mux->hnd, EPOLL_CTL_ADD, hnd, &ev); | ||||
| 			break; | ||||
|  | ||||
| 		case MIO_SYS_MUX_CMD_UPDATE: | ||||
| 			if (MIO_UNLIKELY(!events)) | ||||
| 			{ | ||||
| 				if (dev->dev_cap & MIO_DEV_CAP_WATCH_SUSPENDED) | ||||
| 				{ | ||||
| 					/* no change. keep suspended */ | ||||
| 					return 0; | ||||
| 				} | ||||
| 				else | ||||
| 				{ | ||||
| 					x = epoll_ctl(mux->hnd, EPOLL_CTL_DEL, hnd, &ev); | ||||
| 					if (x >= 0) dev->dev_cap |= MIO_DEV_CAP_WATCH_SUSPENDED; | ||||
| 				} | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				if (dev->dev_cap & MIO_DEV_CAP_WATCH_SUSPENDED) | ||||
| 				{ | ||||
| 					x = epoll_ctl(mux->hnd, EPOLL_CTL_ADD, hnd, &ev); | ||||
| 					if (x >= 0) dev->dev_cap &= ~MIO_DEV_CAP_WATCH_SUSPENDED; | ||||
| 				} | ||||
| 				else | ||||
| 				{ | ||||
| 					x = epoll_ctl(mux->hnd, EPOLL_CTL_MOD, hnd, &ev); | ||||
| 				} | ||||
| 			} | ||||
| 			break; | ||||
|  | ||||
| 		case MIO_SYS_MUX_CMD_DELETE: | ||||
| 			if (dev->dev_cap & MIO_DEV_CAP_WATCH_SUSPENDED)  | ||||
| 			{ | ||||
| 				/* clear the SUSPENDED bit because it's a normal deletion */ | ||||
| 				dev->dev_cap &= ~MIO_DEV_CAP_WATCH_SUSPENDED; | ||||
| 				return 0; | ||||
| 			} | ||||
|  | ||||
| 			x = epoll_ctl(mux->hnd, EPOLL_CTL_DEL, hnd, &ev); | ||||
| 			break; | ||||
|  | ||||
| 		default: | ||||
| 			mio_seterrnum (mio, MIO_EINVAL); | ||||
| 			return -1; | ||||
| 	} | ||||
|  | ||||
| 	if (dev_cap & MIO_DEV_CAP_OUT_WATCHED) ev.events |= EPOLLOUT; | ||||
|  | ||||
| 	if (epoll_ctl(mux->hnd, epoll_cmd[cmd], dev->dev_mth->getsyshnd(dev), &ev) == -1) | ||||
| 	if (x == -1) | ||||
| 	{ | ||||
| 		mio_seterrwithsyserr (mio, 0, errno); | ||||
| 		return -1; | ||||
|  | ||||
| @ -68,7 +68,7 @@ struct mio_sys_mux_t | ||||
| struct mio_sys_mux_t | ||||
| { | ||||
| 	int hnd; | ||||
| 	struct epoll_event revs[100]; /* TODO: is it a good size? */ | ||||
| 	struct epoll_event revs[128]; /* TODO: is it a good size? */ | ||||
| }; | ||||
|  | ||||
| #endif | ||||
|  | ||||
		Reference in New Issue
	
	Block a user