implemented the control pipe for poll
This commit is contained in:
		| @ -34,6 +34,9 @@ | |||||||
| #if defined(USE_POLL) | #if defined(USE_POLL) | ||||||
| #	define MUX_INDEX_INVALID MIO_TYPE_MAX(mio_oow_t) | #	define MUX_INDEX_INVALID MIO_TYPE_MAX(mio_oow_t) | ||||||
| #	define MUX_INDEX_SUSPENDED (MUX_INDEX_INVALID - 1) | #	define MUX_INDEX_SUSPENDED (MUX_INDEX_INVALID - 1) | ||||||
|  |  | ||||||
|  | static int secure_poll_map_slot_for_hnd (mio_t* mio, mio_syshnd_t hnd); | ||||||
|  | static int secure_poll_data_slot_for_insert (mio_t* mio); | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| int mio_sys_initmux (mio_t* mio) | int mio_sys_initmux (mio_t* mio) | ||||||
| @ -63,8 +66,29 @@ int mio_sys_initmux (mio_t* mio) | |||||||
| #endif | #endif | ||||||
|  |  | ||||||
|  |  | ||||||
|  | #if defined(USE_POLL) | ||||||
|  | 	if (secure_poll_map_slot_for_hnd(mio, mux->ctrlp[0]) <= -1 || | ||||||
|  | 	    secure_poll_data_slot_for_insert(mio) <= -1) | ||||||
|  | 	{ | ||||||
|  | 		/* no control pipes if registration fails */ | ||||||
|  | 		close (mux->ctrlp[1]);  | ||||||
|  | 		mux->ctrlp[1] = MIO_SYSHND_INVALID; | ||||||
|  | 		close (mux->ctrlp[0]); | ||||||
|  | 		mux->ctrlp[0] = MIO_SYSHND_INVALID; | ||||||
|  | 	} | ||||||
|  | 	else | ||||||
|  | 	{ | ||||||
|  | 		mio_oow_t idx; | ||||||
|  | 		idx = mux->pd.size++; | ||||||
|  | 		mux->pd.pfd[idx].fd = mux->ctrlp[0]; | ||||||
|  | 		mux->pd.pfd[idx].events = POLLIN; | ||||||
|  | 		mux->pd.pfd[idx].revents = 0; | ||||||
|  | 		mux->pd.dptr[idx] = MIO_NULL; | ||||||
|  | 		mux->map.ptr[mux->ctrlp[0]] = idx; | ||||||
|  | 	} | ||||||
|  |  | ||||||
| #if defined(USE_EPOLL) |  | ||||||
|  | #elif defined(USE_EPOLL) | ||||||
|  |  | ||||||
| #if defined(HAVE_EPOLL_CREATE1) && defined(EPOLL_CLOEXEC) | #if defined(HAVE_EPOLL_CREATE1) && defined(EPOLL_CLOEXEC) | ||||||
| 	mux->hnd = epoll_create1(EPOLL_CLOEXEC); | 	mux->hnd = epoll_create1(EPOLL_CLOEXEC); | ||||||
| @ -99,7 +123,14 @@ epoll_create_done: | |||||||
| 		struct epoll_event ev; | 		struct epoll_event ev; | ||||||
| 		ev.events = EPOLLIN | EPOLLHUP | EPOLLERR; | 		ev.events = EPOLLIN | EPOLLHUP | EPOLLERR; | ||||||
| 		ev.data.ptr = MIO_NULL; | 		ev.data.ptr = MIO_NULL; | ||||||
| 		epoll_ctl(mux->hnd, EPOLL_CTL_ADD, mux->ctrlp[0], &ev); | 		if (epoll_ctl(mux->hnd, EPOLL_CTL_ADD, mux->ctrlp[0], &ev) == -1) | ||||||
|  | 		{ | ||||||
|  | 			/* if ADD fails, close the control pipes and forget them */ | ||||||
|  | 			close (mux->ctrlp[1]);  | ||||||
|  | 			mux->ctrlp[1] = MIO_SYSHND_INVALID; | ||||||
|  | 			close (mux->ctrlp[0]); | ||||||
|  | 			mux->ctrlp[0] = MIO_SYSHND_INVALID; | ||||||
|  | 		} | ||||||
| 	} | 	} | ||||||
| #endif /* USE_EPOLL */ | #endif /* USE_EPOLL */ | ||||||
|  |  | ||||||
| @ -162,6 +193,62 @@ void mio_sys_intrmux (mio_t* mio) | |||||||
| 	if (mux->ctrlp[1] != MIO_SYSHND_INVALID) write (mux->ctrlp[1], "Q", 1); | 	if (mux->ctrlp[1] != MIO_SYSHND_INVALID) write (mux->ctrlp[1], "Q", 1); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | #if defined(USE_POLL) | ||||||
|  | static int secure_poll_map_slot_for_hnd (mio_t* mio, mio_syshnd_t hnd) | ||||||
|  | { | ||||||
|  | 	mio_sys_mux_t* mux = &mio->sysdep->mux; | ||||||
|  |  | ||||||
|  | 	if (hnd >= mux->map.capa) | ||||||
|  | 	{ | ||||||
|  | 		mio_oow_t new_capa; | ||||||
|  | 		mio_oow_t* tmp; | ||||||
|  | 		mio_oow_t idx; | ||||||
|  |  | ||||||
|  | 		new_capa = MIO_ALIGN_POW2((hnd + 1), 256); | ||||||
|  |  | ||||||
|  | 		tmp = mio_reallocmem(mio, mux->map.ptr, new_capa * MIO_SIZEOF(*tmp)); | ||||||
|  | 		if (MIO_UNLIKELY(!tmp)) return -1; | ||||||
|  |  | ||||||
|  | 		for (idx = mux->map.capa; idx < new_capa; idx++) tmp[idx] = MUX_INDEX_INVALID; | ||||||
|  |  | ||||||
|  | 		mux->map.ptr = tmp; | ||||||
|  | 		mux->map.capa = new_capa; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static int secure_poll_data_slot_for_insert (mio_t* mio) | ||||||
|  | { | ||||||
|  | 	mio_sys_mux_t* mux = &mio->sysdep->mux; | ||||||
|  |  | ||||||
|  | 	if (mux->pd.size >= mux->pd.capa) | ||||||
|  | 	{ | ||||||
|  | 		mio_oow_t new_capa; | ||||||
|  | 		struct pollfd* tmp1; | ||||||
|  | 		mio_dev_t** tmp2; | ||||||
|  |  | ||||||
|  | 		new_capa = MIO_ALIGN_POW2(mux->pd.size + 1, 256); | ||||||
|  |  | ||||||
|  | 		tmp1 = mio_reallocmem(mio, mux->pd.pfd, new_capa * MIO_SIZEOF(*tmp1)); | ||||||
|  | 		if (MIO_UNLIKELY(!tmp1)) return -1; | ||||||
|  |  | ||||||
|  | 		tmp2 = mio_reallocmem(mio, mux->pd.dptr, new_capa * MIO_SIZEOF(*tmp2)); | ||||||
|  | 		if (MIO_UNLIKELY(!tmp2)) | ||||||
|  | 		{ | ||||||
|  | 			mio_freemem (mio, tmp1); | ||||||
|  | 			return -1; | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		mux->pd.pfd = tmp1; | ||||||
|  | 		mux->pd.dptr = tmp2; | ||||||
|  | 		mux->pd.capa = new_capa; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
|  | #endif | ||||||
|  |  | ||||||
| int mio_sys_ctrlmux (mio_t* mio, mio_sys_mux_cmd_t cmd, mio_dev_t* dev, int dev_cap) | int mio_sys_ctrlmux (mio_t* mio, mio_sys_mux_cmd_t cmd, mio_dev_t* dev, int dev_cap) | ||||||
| { | { | ||||||
| #if defined(USE_POLL) | #if defined(USE_POLL) | ||||||
| @ -171,6 +258,20 @@ int mio_sys_ctrlmux (mio_t* mio, mio_sys_mux_cmd_t cmd, mio_dev_t* dev, int dev_ | |||||||
|  |  | ||||||
| 	hnd = dev->dev_mth->getsyshnd(dev); | 	hnd = dev->dev_mth->getsyshnd(dev); | ||||||
|  |  | ||||||
|  | #if 1 | ||||||
|  | 	if (cmd == MIO_SYS_MUX_CMD_INSERT) | ||||||
|  | 	{ | ||||||
|  | 		if (secure_poll_map_slot_for_hnd(mio, hnd) <=  -1) return -1; | ||||||
|  | 	} | ||||||
|  | 	else | ||||||
|  | 	{ | ||||||
|  | 		if (hnd >= mux->map.capa) | ||||||
|  | 		{ | ||||||
|  | 			mio_seterrnum (mio, MIO_ENOENT); | ||||||
|  | 			return -1; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | #else | ||||||
| 	if (hnd >= mux->map.capa) | 	if (hnd >= mux->map.capa) | ||||||
| 	{ | 	{ | ||||||
| 		mio_oow_t new_capa; | 		mio_oow_t new_capa; | ||||||
| @ -185,14 +286,14 @@ int mio_sys_ctrlmux (mio_t* mio, mio_sys_mux_cmd_t cmd, mio_dev_t* dev, int dev_ | |||||||
| 		new_capa = MIO_ALIGN_POW2((hnd + 1), 256); | 		new_capa = MIO_ALIGN_POW2((hnd + 1), 256); | ||||||
|  |  | ||||||
| 		tmp = mio_reallocmem(mio, mux->map.ptr, new_capa * MIO_SIZEOF(*tmp)); | 		tmp = mio_reallocmem(mio, mux->map.ptr, new_capa * MIO_SIZEOF(*tmp)); | ||||||
| 		if (!tmp) return -1; | 		if (MIO_UNLIKELY(!tmp)) return -1; | ||||||
|  |  | ||||||
| 		for (idx = mux->map.capa; idx < new_capa; idx++)  | 		for (idx = mux->map.capa; idx < new_capa; idx++) tmp[idx] = MUX_INDEX_INVALID; | ||||||
| 			tmp[idx] = MUX_INDEX_INVALID; |  | ||||||
|  |  | ||||||
| 		mux->map.ptr = tmp; | 		mux->map.ptr = tmp; | ||||||
| 		mux->map.capa = new_capa; | 		mux->map.capa = new_capa; | ||||||
| 	} | 	} | ||||||
|  | #endif | ||||||
|  |  | ||||||
| 	idx = mux->map.ptr[hnd]; | 	idx = mux->map.ptr[hnd]; | ||||||
|  |  | ||||||
| @ -206,6 +307,10 @@ int mio_sys_ctrlmux (mio_t* mio, mio_sys_mux_cmd_t cmd, mio_dev_t* dev, int dev_ | |||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 		do_insert: | 		do_insert: | ||||||
|  | #if 1 | ||||||
|  | 			if (MIO_UNLIKELY(secure_poll_data_slot_for_insert(mio) <=  -1)) return -1; | ||||||
|  | #else | ||||||
|  |  | ||||||
| 			if (mux->pd.size >= mux->pd.capa) | 			if (mux->pd.size >= mux->pd.capa) | ||||||
| 			{ | 			{ | ||||||
| 				mio_oow_t new_capa; | 				mio_oow_t new_capa; | ||||||
| @ -215,10 +320,10 @@ int mio_sys_ctrlmux (mio_t* mio, mio_sys_mux_cmd_t cmd, mio_dev_t* dev, int dev_ | |||||||
| 				new_capa = MIO_ALIGN_POW2(mux->pd.size + 1, 256); | 				new_capa = MIO_ALIGN_POW2(mux->pd.size + 1, 256); | ||||||
|  |  | ||||||
| 				tmp1 = mio_reallocmem(mio, mux->pd.pfd, new_capa * MIO_SIZEOF(*tmp1)); | 				tmp1 = mio_reallocmem(mio, mux->pd.pfd, new_capa * MIO_SIZEOF(*tmp1)); | ||||||
| 				if (!tmp1) return -1; | 				if (MIO_UNLIKELY(!tmp1)) return -1; | ||||||
|  |  | ||||||
| 				tmp2 = mio_reallocmem(mio, mux->pd.dptr, new_capa * MIO_SIZEOF(*tmp2)); | 				tmp2 = mio_reallocmem(mio, mux->pd.dptr, new_capa * MIO_SIZEOF(*tmp2)); | ||||||
| 				if (!tmp2) | 				if (MIO_UNLIKELY(!tmp2)) | ||||||
| 				{ | 				{ | ||||||
| 					mio_freemem (mio, tmp1); | 					mio_freemem (mio, tmp1); | ||||||
| 					return -1; | 					return -1; | ||||||
| @ -228,6 +333,7 @@ int mio_sys_ctrlmux (mio_t* mio, mio_sys_mux_cmd_t cmd, mio_dev_t* dev, int dev_ | |||||||
| 				mux->pd.dptr = tmp2; | 				mux->pd.dptr = tmp2; | ||||||
| 				mux->pd.capa = new_capa; | 				mux->pd.capa = new_capa; | ||||||
| 			} | 			} | ||||||
|  | #endif | ||||||
|  |  | ||||||
| 			idx = mux->pd.size++; | 			idx = mux->pd.size++; | ||||||
|  |  | ||||||
| @ -422,7 +528,15 @@ int mio_sys_waitmux (mio_t* mio, const mio_ntime_t* tmout, mio_sys_mux_evtcb_t e | |||||||
|  |  | ||||||
| 	for (i = 0; i < mux->pd.size; i++) | 	for (i = 0; i < mux->pd.size; i++) | ||||||
| 	{ | 	{ | ||||||
| 		if (mux->pd.pfd[i].fd >= 0 && mux->pd.pfd[i].revents) | 		if (MIO_UNLIKELY(mux->ctrlp[0] != MIO_SYSHND_INVALID && mux->pd.pfd[i].fd == mux->ctrlp[0])) | ||||||
|  | 		{ | ||||||
|  | 			/* internal pipe for signaling */ | ||||||
|  |  | ||||||
|  | 			/* mux->pd.dptr[i] must be MIO_NULL */ | ||||||
|  | 			mio_uint8_t tmp[16]; | ||||||
|  | 			while (read(mux->ctrlp[0], tmp, MIO_SIZEOF(tmp)) > 0) ; | ||||||
|  | 		} | ||||||
|  | 		else if (mux->pd.pfd[i].fd >= 0 && mux->pd.pfd[i].revents) | ||||||
| 		{ | 		{ | ||||||
| 			int events = 0; | 			int events = 0; | ||||||
| 			mio_dev_t* dev; | 			mio_dev_t* dev; | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user