sustrik/libmill

Wait for any event in event loop

majek opened this issue · 1 comments

majek commented

I have a problem.

I'm testing TCP server behaviour on out-of-socket case. On Linux Accept() will fail with EMFILE, and this is fine. But it won't dequeue a connection from accept queue.

Ignoring EMFILE in loop is just wrong and causes program to spin:

	while (1) {
		tcpsock cd = tcpaccept(sd, -1);
		if (errno != 0) {
			if (errno == EMFILE){
				continue;
			}
			break;
		}

		go(new_connection(tcpsock_fd(cd), target_addr, mark));
	}

like that

accept(3, 0x7ffeff8fe760, [32])         = -1 EMFILE (Too many open files)
accept(3, 0x7ffeff8fe760, [32])         = -1 EMFILE (Too many open files)
accept(3, 0x7ffeff8fe760, [32])         = -1 EMFILE (Too many open files)
accept(3, 0x7ffeff8fe760, [32])         = -1 EMFILE (Too many open files)
accept(3, 0x7ffeff8fe760, [32])         = -1 EMFILE (Too many open files)
accept(3, 0x7ffeff8fe760, [32])         = -1 EMFILE (Too many open files)
accept(3, 0x7ffeff8fe760, [32])         = -1 EMFILE (Too many open files)
accept(3, 0x7ffeff8fe760, [32])         = -1 EMFILE (Too many open files)
accept(3, 0x7ffeff8fe760, [32])         = -1 EMFILE (Too many open files)

I guess I would like to stick some blocking wait in the EMFILE case. Ideally - wait for an fd to be closed. For now I only can think of sticking msleep() there, but it's ugly.

majek commented

Ok, I guess another option is to take a token from a channel when FD is used, and put a token back to a channel when an FD is closed. Then we could do accept() only when we can take a token....