static int lua52_closurecallback(lua_State *s) { float stateindex; float funcindex; // pull our GovalueRegistry indexes from the closure's upvalues stateindex = lua_tonumber(s, lua_upvalueindex(1)); funcindex = lua_tonumber(s, lua_upvalueindex(2)); // Call back into golang luajit.docallback return docallback(stateindex, funcindex); }
/* Callback when connect(2) succeeds or fails. */ static int callback_connect(void * cookie) { struct connect_cookie * C = cookie; int sockerr; socklen_t sockerrlen = sizeof(int); /* Did we succeed? */ if (getsockopt(C->s, SOL_SOCKET, SO_ERROR, &sockerr, &sockerrlen)) goto err1; if (sockerr != 0) goto failed; /* * Perform the callback (this can be done here rather than being * scheduled as an immediate callback, as we're already running from * callback context). */ return (docallback(C)); failed: /* Close the socket which failed to connect. */ close(C->s); /* We don't have an open socket any more. */ C->s = -1; /* This address didn't work. */ C->sas++; /* Try other addresses until we run out of options. */ return (tryconnect(C)); err1: close(C->s); free(C); /* Fatal error! */ return (-1); }
/* The socket is ready for reading/writing. */ static int callback_buf(void * cookie) { struct network_write_cookie * C = cookie; size_t oplen; ssize_t len; #if MSG_NOSIGNAL == 0 void (*oldsig)(int); #endif /* If we don't have MSG_NOSIGNAL, catch SIGPIPE. */ #if MSG_NOSIGNAL == 0 if ((oldsig = signal(SIGPIPE, SIG_IGN)) == SIG_ERR) { warnp("signal(SIGPIPE)"); goto failed; } #endif /* Attempt to read/write data to/from the buffer. */ oplen = C->buflen - C->bufpos; len = send(C->fd, C->buf + C->bufpos, oplen, MSG_NOSIGNAL); /* We should never see a send length of zero. */ assert(len != 0); /* If we set a SIGPIPE handler, restore the old one. */ #if MSG_NOSIGNAL == 0 if (signal(SIGPIPE, oldsig) == SIG_ERR) { warnp("signal(SIGPIPE)"); goto failed; } #endif /* Failure? */ if (len == -1) { /* Was it really an error, or just a try-again? */ if ((errno == EAGAIN) || (errno == EWOULDBLOCK) || (errno == EINTR)) goto tryagain; /* Something went wrong. */ goto failed; } /* We processed some data. Do we need to keep going? */ if ((C->bufpos += len) < C->minlen) goto tryagain; /* Invoke the callback and return. */ return (docallback(C, C->bufpos)); tryagain: /* Reset the event. */ if (events_network_register(callback_buf, C, C->fd, EVENTS_NETWORK_OP_WRITE)) goto failed; /* Callback was reset. */ return (0); failed: /* Invoke the callback with a failure status and return. */ return (docallback(C, -1)); }