public void readyAccept(SelectableChannel ch) throws Pausable {
if (log.isLoggable(Level.FINE))
log.fine("readyAccept " + this);
if (state == TCP_STATE_ACCEPTING) {
InetSocket sock;
try {
sock = fd.accept();
} catch (IOException e) {
sock = null;
// return //
}
// we got a connection
sock_select(ERL_DRV_ACCEPT, SelectMode.CLEAR);
state = TCP_STATE_LISTEN;
AsyncOp peek = opt.peek();
if (peek != null) {
driver_demonitor_process(peek.monitor);
}
driver_cancel_timer();
if (sock == null) {
// return //
} else {
if (peek == null) {
sock_close(fd.channel());
async_error(Posix.EINVAL);
return;
}
TCPINet accept_desc = this.copy(peek.caller, sock);
accept_desc.state = TCP_STATE_CONNECTED;
try {
sock.setNonBlocking();
} catch (IOException e) {
e.printStackTrace();
}
// accept_desc.select(sock.channel(), ERL_DRV_READ,
// SelectMode.SET);
async_ok_port(peek.caller, accept_desc.port());
}
} else if (state == TCP_STATE_MULTI_ACCEPTING) {
while (state == TCP_STATE_MULTI_ACCEPTING) {
int err = 0;
InetSocket sock;
try {
sock = fd.accept();
if (sock == null) {
sock_select(ERL_DRV_ACCEPT, SelectMode.SET);
return;
}
} catch (IOException e) {
sock = null;
err = IO.exception_to_posix_code(e);
}
AsyncMultiOp multi = deq_multi_op();
if (multi == null) {
return; /* -1; close? */
}
if (this.multi_first == null) {
// we got a connection, and there are no more multi's waiting
sock_select(ERL_DRV_ACCEPT, SelectMode.CLEAR);
state = TCP_STATE_LISTEN;
}
if (multi.timeout != null) {
remove_multi_timer(multi.timeout);
}
driver_demonitor_process(multi.op.monitor);
if (sock == null) {
send_async_error(multi.op.id, multi.op.caller,
EAtom.intern(Posix.errno_id(err).toLowerCase()));
// return //
} else {
TCPINet accept_desc = this.copy(multi.op.caller, sock);
accept_desc.state = TCP_STATE_CONNECTED;
try {
sock.setNonBlocking();
} catch (IOException e) {
e.printStackTrace();
}
// accept_desc.select(sock.channel(), ERL_DRV_READ,
// SelectMode.SET);