KNIEXPORT KNI_RETURNTYPE_INT Java_com_sun_cldc_io_j2me_socket_Protocol_writeBuf() { int result; int fd = KNI_GetParameterAsInt(1); int offset = KNI_GetParameterAsInt(3); int length = KNI_GetParameterAsInt(4); KNI_StartHandles(1); KNI_DeclareHandle(buffer_object); KNI_GetParameterAsObject(2, buffer_object); char *buffer = (char *) SNI_GetRawArrayPointer(buffer_object) + offset; result = jvm_send(fd, buffer, length, 0); // We rely on open0() for setting the socket to non-blocking KNI_EndHandles(); if (result < 0) { int err_code = GET_LAST_ERROR(); if (err_code == EWOULDBLOCK) { if (SNI_GetReentryData(NULL) == NULL) { BlockingSocket *socket = (BlockingSocket *) SNI_AllocateReentryData(sizeof(*socket)); socket->fd = fd; socket->check_flags = CHECK_WRITE; } SNI_BlockThread(); } } KNI_ReturnInt(result); }
/** * The function blocks the calling thread if Transaction Store is locked. * <p>Java declaration: * <pre> * private native void lockStore(); */ KNIEXPORT KNI_RETURNTYPE_VOID Java_com_sun_j2me_payment_TransactionStorageImpl_lockStore() { MidpReentryData *info = NULL; KNI_StartHandles(1); KNI_DeclareHandle(thisObject); KNI_GetThisPointer(thisObject); if (locked == KNI_FALSE) { locked = KNI_TRUE; KNI_GetThisPointer(thisObject); getStorageOpenFlag(thisObject)->isOpen = (jboolean)KNI_TRUE; } else { info = (MidpReentryData*)SNI_GetReentryData(NULL); if (info == NULL) { info = (MidpReentryData*) (SNI_AllocateReentryData(sizeof (MidpReentryData))); } info->waitingFor = PAYMENT_TRANSACTION_STORE_SIGNAL; info->descriptor = 0; info->status = KNI_FALSE; info->pResult = NULL; /* try again later */ SNI_BlockThread(); } KNI_EndHandles(); KNI_ReturnVoid(); }
/** * Block this thread until unblocked. * Initialize the reentry data needed to unblock this thread later. * Only the waitingFor setting is used. * The status is set to STATUS_OK. * If canceled the status will be set to cancelled. */ static void blockThread() { /* Initialize the re-entry data so later this thread can * be unblocked. */ MidpReentryData* p = (MidpReentryData*)(SNI_GetReentryData(NULL)); if (p == NULL) { p = (MidpReentryData*) (SNI_AllocateReentryData(sizeof (MidpReentryData))); } p->waitingFor = JSR211_SIGNAL; p->status = JSR211_INVOKE_OK; SNI_BlockThread(); }
/** * Blocks the current Java thread. The MidpReentryData block for * the current Java thread is set to the passed values. * * @param waitingFor set into MidpReentryData.waitingFor * @param descriptor set into MidpReentryData.descriptor * @param pResult set into MidpReentryData.pResult */ void midp_thread_wait(midpSignalType waitingFor, int descriptor, void* pResult) { MidpReentryData* p = (MidpReentryData*)SNI_GetReentryData(NULL); if (p == NULL) { p = (MidpReentryData*) (SNI_AllocateReentryData(sizeof (MidpReentryData))); if (p == NULL) { REPORT_CRIT(LC_CORE, "midp_cond_wait: failed to allocate reentry data"); } } p->descriptor = descriptor; p->waitingFor = waitingFor; p->status = 0; p->pResult = pResult; SNI_BlockThread(); }
KNIEXPORT KNI_RETURNTYPE_INT Java_com_sun_cldc_io_j2me_socket_Protocol_readBuf() { int result; int fd = KNI_GetParameterAsInt(1); int offset = KNI_GetParameterAsInt(3); int length = KNI_GetParameterAsInt(4); KNI_StartHandles(1); KNI_DeclareHandle(buffer_object); KNI_GetParameterAsObject(2, buffer_object); char *buffer = (char *) SNI_GetRawArrayPointer(buffer_object) + offset; result = jvm_recv(fd, buffer, length, 0); // We rely on open0() for setting the socket to non-blocking KNI_EndHandles(); if (result == 0) { // If remote side has shut down the connection gracefully, and all // data has been received, recv() will complete immediately with // zero bytes received. // // This is true for Win32/CE and Linux result = -1; } else if (result < 0) { int err_code = GET_LAST_ERROR(); if (err_code == EWOULDBLOCK) { if (SNI_GetReentryData(NULL) == NULL) { BlockingSocket *socket = (BlockingSocket *)SNI_AllocateReentryData(sizeof(*socket)); socket->fd = fd; socket->check_flags = CHECK_READ; } SNI_BlockThread(); } } KNI_ReturnInt(result); }
KNIEXPORT KNI_RETURNTYPE_INT Java_com_sun_cldc_io_j2me_socket_Protocol_writeByte() { int fd = KNI_GetParameterAsInt(1); char byte = (char) KNI_GetParameterAsInt(2); // We rely on open0() for setting the socket to non-blocking int result = jvm_send(fd, &byte, 1, 0); if (result < 0) { int err_code = GET_LAST_ERROR(); if (err_code == EWOULDBLOCK) { if (SNI_GetReentryData(NULL) == NULL) { BlockingSocket *socket = (BlockingSocket *)SNI_AllocateReentryData(sizeof(*socket)); socket->fd = fd; socket->check_flags = CHECK_WRITE; } SNI_BlockThread(); } } KNI_ReturnInt(result); }
KNIEXPORT KNI_RETURNTYPE_INT Java_com_sun_cldc_io_j2me_socket_Protocol_readByte() { jint result = -1; unsigned char byte; int fd = KNI_GetParameterAsInt(1); int n = jvm_recv(fd, (char*)&byte, 1, 0); if (n == 1) { result = byte; // do not sign-extend GUARANTEE(0 <= result && result <= 255, "no sign extension"); } else if (n == 0) { // If remote side has shut down the connection gracefully, and all // data has been received, recv() will complete immediately with // zero bytes received. // // This is true for Win32/CE and Linux result = -1; } else { int err_code = GET_LAST_ERROR(); if (err_code == EWOULDBLOCK) { if (SNI_GetReentryData(NULL) == NULL) { BlockingSocket *socket = (BlockingSocket *)SNI_AllocateReentryData(sizeof(*socket)); socket->fd = fd; socket->check_flags = CHECK_READ; } SNI_BlockThread(); } else { result = -1; } } KNI_ReturnInt(result); }
KNIEXPORT KNI_RETURNTYPE_INT Java_com_sun_cldc_io_j2me_socket_Protocol_open0() { init_sockets(); SocketOpenParameter *p = (SocketOpenParameter*) SNI_GetReentryData(NULL); if (p == NULL) { p = (SocketOpenParameter*) SNI_AllocateReentryData(sizeof(*p)); p->fd = -1; struct hostent *phostent; KNI_StartHandles(1); KNI_DeclareHandle(hostname_object); KNI_GetParameterAsObject(1, hostname_object); // hostname is always NUL terminated. See socket/Protocol.java for detail. char *hostname = (char*) SNI_GetRawArrayPointer(hostname_object); phostent = (struct hostent*)jvm_gethostbyname(hostname); KNI_EndHandles(); if (phostent == NULL) { KNI_ReturnInt(-1); } struct sockaddr_in destination_sin; destination_sin.sin_family = AF_INET; int port = KNI_GetParameterAsInt(2); destination_sin.sin_port = jvm_htons(port); jvm_memcpy((char *) &destination_sin.sin_addr, phostent->h_addr, phostent->h_length); p->fd = jvm_socket(AF_INET, SOCK_STREAM, 0); if (p->fd < 0) { KNI_ReturnInt(-1); } if (!set_blocking_flags(&p->fd, /*is_blocking*/ KNI_FALSE)) { KNI_ReturnInt(-1); } if (jvm_connect(p->fd, (struct sockaddr *) &destination_sin, sizeof(destination_sin)) < 0) { int err_code = GET_LAST_ERROR(); if (err_code == EINPROGRESS) { // When the socket is ready for connect, it becomes *writable* // (according to BSD socket spec of select()) p->check_flags = CHECK_WRITE | CHECK_EXCEPTION; SNI_BlockThread(); } else { jvm_shutdown(p->fd, 2); closesocket(p->fd); p->fd = -1; } } KNI_ReturnInt(p->fd); } else { // When we come to here, a CheckEvent() call has reported one of the // following: // [1] connect() has succeeded. In this case we return the socket fd. // [2] connect() has failed. In this case CheckEvent has already closed // the socket and set p->fd to -1. So we'd be returning -1. KNI_ReturnInt(p->fd); } }