Modified: commons/sandbox/runtime/trunk/src/main/native/os/win32/fsysio.c URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/os/win32/fsysio.c?rev=883810&r1=883809&r2=883810&view=diff ============================================================================== --- commons/sandbox/runtime/trunk/src/main/native/os/win32/fsysio.c (original) +++ commons/sandbox/runtime/trunk/src/main/native/os/win32/fsysio.c Tue Nov 24 18:47:13 2009 @@ -441,7 +441,7 @@ return fdo; } -static int do_lock(acr_file_t *f, DWORD flags) +int do_lock(acr_file_t *f, DWORD flags) { if (f->blocking == BLK_OFF) { if (IS_INVALID_HANDLE(f->overlap.hEvent)) { @@ -490,7 +490,7 @@ } -static int do_unlock(acr_file_t *f) +int do_unlock(acr_file_t *f) { int rc = 0; OVERLAPPED opp; @@ -696,1771 +696,3 @@ else return 0; } - -static DWORD overlapped_wait(acr_file_t *f, DWORD *nbytes) -{ - DWORD ws; - DWORD rc = 0; - - do { - switch (ws = ACR_WaitForObjectOrSignal(f->overlap.hEvent, - f->timeout)) { - case WAIT_IO_COMPLETION: - case WAIT_ABANDONED_0: - case WAIT_ABANDONED_1: - case WAIT_OBJECT_0: - /* Signal event is set. - * Get it's status. - */ - rc = ACR_DeliverSignals(); - break; - case WAIT_OBJECT_1: - /* Operation success */ - rc = 0; - break; - case WAIT_FAILED: - /* We got the error while waiting - */ - rc = ACR_GET_OS_ERROR(); - break; - case WAIT_TIMEOUT: - rc = ACR_TIMEUP; - break; - default: - rc = ACR_EINVAL; - break; - } - } while (rc == ACR_EINTR); - - if (rc) { - /* There is one case that represents entirely - * successful operations, otherwise we will cancel - * the operation in progress. - */ - CancelIo(f->fd); - } - if (!GetOverlappedResult(f->fd, - &f->overlap, - nbytes, - FALSE)) { - rc = GetLastError(); - if (rc == ERROR_IO_INCOMPLETE || - rc == ERROR_OPERATION_ABORTED) - rc = ACR_TIMEUP; - } - return rc; -} - -static DWORD overlapped_wait_all(acr_file_t *f, DWORD *nbytes) -{ - DWORD ws; - DWORD rc = 0; - - do { - switch (ws = ACR_WaitForObjectOrSignal(f->overlap.hEvent, INFINITE)) { - case WAIT_IO_COMPLETION: - case WAIT_ABANDONED_0: - case WAIT_ABANDONED_1: - case WAIT_OBJECT_0: - /* Signal event is set. - * Get it's status. - */ - rc = ACR_DeliverSignals(); - break; - case WAIT_OBJECT_1: - /* Operation success */ - rc = 0; - break; - case WAIT_FAILED: - /* We got the error while waiting - */ - rc = ACR_GET_OS_ERROR(); - break; - default: - rc = ACR_EINVAL; - break; - } - } while (rc == ACR_EINTR); - - if (rc) { - /* There is one case that represents entirely - * successful operations, otherwise we will cancel - * the operation in progress. - */ - CancelIo(f->fd); - } - if (!GetOverlappedResult(f->fd, - &f->overlap, - nbytes, - FALSE)) { - rc = GetLastError(); - if (rc == ERROR_IO_INCOMPLETE || - rc == ERROR_OPERATION_ABORTED) - rc = ACR_TIMEUP; - } - return rc; -} - -ACR_IO_EXPORT_DECLARE(jint, FileSystemIo, read0)(ACR_JNISTDARGS, - jint file) -{ - unsigned char c; - DWORD rd = 0; - DWORD rc = 0; - LPOVERLAPPED lpo = NULL; - acr_file_t *f = (acr_file_t *)ACR_IOH_FDATA(file); - - if (ACR_IOH_FTYPE(file) != ACR_DT_FILE) { - ACR_THROW_EX_IF_ERR(ACR_EX_INVALID_DESC, ACR_EFTYPE); - return -1; - } - if (IS_INVALID_HANDLE(f)) { - ACR_THROW_EX_IF_ERR(ACR_EX_CLOSED_DESC, ACR_EBADF); - return -1; - } - if (f->eof) { - return -1; - } - - if (f->blocking == BLK_OFF) { - if (f->timeout == 0 && f->type == ACR_FT_PIPE) { - if (!PeekNamedPipe(f->fd, NULL, 0, NULL, &rd, NULL)) { - rc = GetLastError(); - if (rc == ERROR_BROKEN_PIPE) { - f->eof = 1; - return -1; - } - else { - f->eof = 1; - ACR_THROW_IO_IF_ERR(rc); - return -1; - } - } - else { - if (rd == 0) { - ACR_DescriptorSetErrEx(_E, f->descriptor, ACR_TIMEUP); - return -1; - } - } - } - lpo = &f->overlap; - if (IS_INVALID_HANDLE(lpo->hEvent)) - lpo->hEvent = CreateEvent(NULL, TRUE, TRUE, NULL); - if (IS_INVALID_HANDLE(lpo->hEvent)) - return ACR_GET_OS_ERROR(); - lpo->Offset = (DWORD)(f->pos); - lpo->OffsetHigh = (DWORD)(f->pos >> 32); - } - if (ReadFile(f->fd, &c, 1, &rd, lpo)) { - /* All done. Update the position and return - */ - if (rd) { - f->pos += rd; - return c; - } - else { - f->eof = 1; - return -1; - } - } - switch (rc = GetLastError()) { - case ERROR_HANDLE_EOF: - case ERROR_BROKEN_PIPE: - rc = 0; - f->eof = 1; - break; - case ERROR_IO_PENDING: - switch (rc = overlapped_wait(f, &rd)) { - case 0: - if (rd) { - f->pos += rd; - return c; - } - else - f->eof = 1; - break; - case ERROR_HANDLE_EOF: - case ERROR_BROKEN_PIPE: - rc = 0; - f->eof = 1; - break; - default: - break; - } - break; - default: - break; - } - if (f->eof) - return -1; - - ACR_DescriptorSetErrEx(_E, f->descriptor, rc); - switch (rc) { - case 0: - case ACR_TIMEUP: - case ERROR_OPERATION_ABORTED: - ACR_THROW_EX_IF_ERR(ACR_EX_ETIMEOUT, rc); - break; - case ERROR_INVALID_HANDLE: - ACR_THROW_EX_IF_ERR(ACR_EX_ACLOSED_DESC, rc); - break; - default: - ACR_THROW_IO_IF_ERR(rc); - break; - } - return -1; -} - -ACR_IO_EXPORT_DECLARE(jint, FileSystemIo, read1)(ACR_JNISTDARGS, - jint file, - jbyteArray buf, - jint off, - jint len) -{ - jbyte *bb = NULL; - jbyte *bc = NULL; - DWORD po = (DWORD)off; - DWORD cs = (DWORD)len; - DWORD rd = 0; - DWORD rc = 0; - LPOVERLAPPED lpo = NULL; - jbyte onstack[ACR_PBUFF_SIZ]; - acr_file_t *f = (acr_file_t *)ACR_IOH_FDATA(file); - - if (ACR_IOH_FTYPE(file) != ACR_DT_FILE) { - ACR_THROW_EX_IF_ERR(ACR_EX_INVALID_DESC, ACR_EFTYPE); - return -1; - } - if (IS_INVALID_HANDLE(f)) { - ACR_THROW_EX_IF_ERR(ACR_EX_CLOSED_DESC, ACR_EBADF); - return -1; - } - if (f->eof) { - return -1; - } - if (f->blocking == BLK_OFF) { - if (f->timeout == 0 && f->type == ACR_FT_PIPE) { - if (!PeekNamedPipe(f->fd, NULL, 0, NULL, &rd, NULL)) { - rc = GetLastError(); - if (rc == ERROR_BROKEN_PIPE) { - f->eof = 1; - return -1; - } - else { - ACR_THROW_IO_IF_ERR(rc); - return -1; - } - } - else { - if (rd == 0) { - ACR_DescriptorSetErrEx(_E, f->descriptor, ACR_TIMEUP); - return 0; - } - else { - /* Update read size that can be done - * without blocking - */ - if (cs > rd) - cs = rd; - } - } - } - lpo = &f->overlap; - if (IS_INVALID_HANDLE(lpo->hEvent)) - lpo->hEvent = CreateEvent(NULL, TRUE, TRUE, NULL); - if (IS_INVALID_HANDLE(lpo->hEvent)) { - ACR_THROW_IO_ERRNO(); - return -1; - } - lpo->Offset = (DWORD)(f->pos); - lpo->OffsetHigh = (DWORD)(f->pos >> 32); - } - if (cs > (DWORD)sizeof(onstack)) { - if (cs > (1024 * 1024)) { - bc = (*_E)->GetByteArrayElements(_E, buf, NULL); - if (bc) - bb = bc + po; - } - else - bb = ACR_Malloc(_E, THROW_FMARK, cs); - } - else - bb = onstack; - if (!bb) { - /* Exception was already thrown */ - return -1; - } - rc = 0; - if (ReadFile(f->fd, bb, cs, &rd, lpo)) { - /* All done. Update the position and return - */ - if (rd) - f->pos += rd; - else - f->eof = 1; - goto finally; - } - switch (rc = GetLastError()) { - case ERROR_HANDLE_EOF: - case ERROR_BROKEN_PIPE: - rc = 0; - f->eof = 1; - break; - case ERROR_IO_PENDING: - switch (rc = overlapped_wait(f, &rd)) { - case 0: - if (rd) { - f->pos += rd; - goto finally; - } - else - f->eof = 1; - break; - case ERROR_HANDLE_EOF: - case ERROR_BROKEN_PIPE: - rc = 0; - f->eof = 1; - break; - default: - break; - } - break; - default: - break; - } - -finally: - if (rd) { - if (bc) { - (*_E)->ReleaseByteArrayElements(_E, buf, bc, 0); - return (jint)rd; - } - else { - (*_E)->SetByteArrayRegion(_E, buf, (jsize)po, (jsize)rd, bb); - } - } - if (bb != onstack) { - if (bc) - (*_E)->ReleaseByteArrayElements(_E, buf, bc, JNI_ABORT); - else - x_free(bb); - } - if (rd > 0) - return (jint)rd; - if (f->eof) - return -1; - - ACR_DescriptorSetErrEx(_E, f->descriptor, rc); - switch (rc) { - case 0: - case ACR_TIMEUP: - case ERROR_OPERATION_ABORTED: - return 0; - break; - case ERROR_INVALID_HANDLE: - ACR_THROW_EX_IF_ERR(ACR_EX_ACLOSED_DESC, rc); - break; - default: - ACR_THROW_IO_IF_ERR(rc); - break; - } - return -1; -} - -ACR_IO_EXPORT_DECLARE(jlong, FileSystemIo, read2)(ACR_JNISTDARGS, - jint file, - jobject ptr, - jlong off, - jlong len) -{ - size_t pl; - DWORD po = (DWORD)off; - DWORD cs = (DWORD)len; - DWORD rd = 0; - DWORD rc = 0; - LPOVERLAPPED lpo = NULL; - jbyte *pb; - acr_file_t *f = (acr_file_t *)ACR_IOH_FDATA(file); - - if (ACR_IOH_FTYPE(file) != ACR_DT_FILE) { - ACR_THROW_EX_IF_ERR(ACR_EX_INVALID_DESC, ACR_EFTYPE); - return -1; - } - if (IS_INVALID_HANDLE(f)) { - ACR_THROW_EX_IF_ERR(ACR_EX_CLOSED_DESC, ACR_EBADF); - return -1; - } - if (f->eof) { - return -1; - } - if (f->blocking == BLK_OFF) { - if (f->timeout == 0 && f->type == ACR_FT_PIPE) { - if (!PeekNamedPipe(f->fd, NULL, 0, NULL, &rd, NULL)) { - rc = GetLastError(); - if (rc == ERROR_BROKEN_PIPE) { - f->eof = 1; - return -1; - } - else { - ACR_THROW_IO_IF_ERR(rc); - return -1; - } - } - else { - if (rd == 0) { - ACR_DescriptorSetErrEx(_E, f->descriptor, ACR_TIMEUP); - return 0; - } - else { - /* Update read size that can be done - * without blocking - */ - if (cs > rd) - cs = rd; - } - } - } - lpo = &f->overlap; - if (IS_INVALID_HANDLE(lpo->hEvent)) - lpo->hEvent = CreateEvent(NULL, TRUE, TRUE, NULL); - if (IS_INVALID_HANDLE(lpo->hEvent)) { - ACR_THROW_IO_ERRNO(); - return -1; - } - lpo->Offset = (DWORD)(f->pos); - lpo->OffsetHigh = (DWORD)(f->pos >> 32); - } - pb = (jbyte *)ACR_PointerGet(_E, ptr, &pl); - if (!pb) { - ACR_ThrowException(_E, THROW_NMARK, ACR_EX_ENULL, 0); - return -1; - } - if ((po + cs) > (DWORD)pl) { - ACR_ThrowException(_E, THROW_NMARK, ACR_EX_EINDEX, 0); - return -1; - } - rc = 0; - if (ReadFile(f->fd, pb + po, cs, &rd, lpo)) { - /* All done. Update the position and return - */ - if (rd) - f->pos += rd; - else - f->eof = 1; - goto finally; - } - switch (rc = GetLastError()) { - case ERROR_HANDLE_EOF: - case ERROR_BROKEN_PIPE: - rc = 0; - f->eof = 1; - break; - case ERROR_IO_PENDING: - switch (rc = overlapped_wait(f, &rd)) { - case 0: - if (rd) { - f->pos += rd; - goto finally; - } - else - f->eof = 1; - break; - case ERROR_HANDLE_EOF: - case ERROR_BROKEN_PIPE: - rc = 0; - f->eof = 1; - break; - default: - break; - } - break; - default: - break; - } - -finally: - if (rd > 0) - return (jlong)rd; - if (f->eof) - return -1; - - ACR_DescriptorSetErrEx(_E, f->descriptor, rc); - switch (rc) { - case 0: - case ACR_TIMEUP: - case ERROR_OPERATION_ABORTED: - return 0; - break; - case ERROR_INVALID_HANDLE: - ACR_THROW_EX_IF_ERR(ACR_EX_ACLOSED_DESC, rc); - break; - default: - ACR_THROW_IO_IF_ERR(rc); - break; - } - return -1; -} - -ACR_IO_EXPORT_DECLARE(jint, FileSystemIo, read3)(ACR_JNISTDARGS, - jint file, - jobject dbb, - jint off, - jint len) -{ -#if defined(_DEBUG) - DWORD pl; -#endif - DWORD po = (DWORD)off; - DWORD cs = (DWORD)len; - DWORD rd = 0; - DWORD rc = 0; - LPOVERLAPPED lpo = NULL; - jbyte *pb; - acr_file_t *f = (acr_file_t *)ACR_IOH_FDATA(file); - - if (ACR_IOH_FTYPE(file) != ACR_DT_FILE) { - ACR_THROW_EX_IF_ERR(ACR_EX_INVALID_DESC, ACR_EFTYPE); - return -1; - } - if (IS_INVALID_HANDLE(f)) { - ACR_THROW_EX_IF_ERR(ACR_EX_CLOSED_DESC, ACR_EBADF); - return -1; - } - if (f->eof) { - return -1; - } - if (f->blocking == BLK_OFF) { - if (f->timeout == 0 && f->type == ACR_FT_PIPE) { - if (!PeekNamedPipe(f->fd, NULL, 0, NULL, &rd, NULL)) { - rc = GetLastError(); - if (rc == ERROR_BROKEN_PIPE) { - f->eof = 1; - return -1; - } - else { - ACR_THROW_IO_IF_ERR(rc); - return -1; - } - } - else { - if (rd == 0) { - ACR_DescriptorSetErrEx(_E, f->descriptor, ACR_TIMEUP); - return 0; - } - else { - /* Update read size that can be done - * without blocking - */ - if (cs > rd) - cs = rd; - } - } - } - lpo = &f->overlap; - if (IS_INVALID_HANDLE(lpo->hEvent)) - lpo->hEvent = CreateEvent(NULL, TRUE, TRUE, NULL); - if (IS_INVALID_HANDLE(lpo->hEvent)) { - ACR_THROW_IO_ERRNO(); - return -1; - } - lpo->Offset = (DWORD)(f->pos); - lpo->OffsetHigh = (DWORD)(f->pos >> 32); - } - pb = (jbyte *)(*_E)->GetDirectBufferAddress(_E, dbb); - if (!pb) { - ACR_ThrowException(_E, THROW_NMARK, ACR_EX_ENULL, 0); - return -1; - } -#if defined(_DEBUG) - pl = (DWORD)(*_E)->GetDirectBufferCapacity(_E, dbb); - if ((po + cs) > pl) { - ACR_ThrowException(_E, THROW_NMARK, ACR_EX_EINDEX, 0); - return -1; - } -#endif - if (ReadFile(f->fd, pb + po, cs, &rd, lpo)) { - /* All done. Update the position and return - */ - if (rd) - f->pos += rd; - else - f->eof = 1; - goto finally; - } - switch (rc = GetLastError()) { - case ERROR_HANDLE_EOF: - case ERROR_BROKEN_PIPE: - rc = 0; - f->eof = 1; - break; - case ERROR_IO_PENDING: - switch (rc = overlapped_wait(f, &rd)) { - case 0: - if (rd) { - f->pos += rd; - goto finally; - } - else - f->eof = 1; - break; - case ERROR_HANDLE_EOF: - case ERROR_BROKEN_PIPE: - rc = 0; - f->eof = 1; - break; - default: - break; - } - break; - default: - break; - } - -finally: - if (rd > 0) - return (jint)rd; - if (f->eof) - return -1; - - ACR_DescriptorSetErrEx(_E, f->descriptor, rc); - switch (rc) { - case 0: - case ACR_TIMEUP: - case ERROR_OPERATION_ABORTED: - return 0; - break; - case ERROR_INVALID_HANDLE: - ACR_THROW_EX_IF_ERR(ACR_EX_ACLOSED_DESC, rc); - break; - default: - ACR_THROW_IO_IF_ERR(rc); - break; - } - return -1; -} - -ACR_IO_EXPORT_DECLARE(jint, FileSystemIo, write0)(ACR_JNISTDARGS, - jint file, - jint b) -{ - unsigned char c = (unsigned char)(b & 0xFF); - DWORD rc = 0; - DWORD wr = 0; - int locked = 0; - LPOVERLAPPED lpo = NULL; - acr_file_t *f = (acr_file_t *)ACR_IOH_FDATA(file); - - if (ACR_IOH_FTYPE(file) != ACR_DT_FILE) { - ACR_THROW_EX_IF_ERR(ACR_EX_INVALID_DESC, ACR_EFTYPE); - return -1; - } - if (IS_INVALID_HANDLE(f)) { - ACR_THROW_EX_IF_ERR(ACR_EX_CLOSED_DESC, ACR_EBADF); - return -1; - } - if (f->flags & ACR_FOPEN_APPEND) { - LARGE_INTEGER os; - LARGE_INTEGER op; - - EnterCriticalSection(&f->lock); - /* apr_file_lock will mutex the file across processes. - * The call to apr_thread_mutex_lock is added to avoid - * a race condition between LockFile and WriteFile - * that occasionally leads to deadlocked threads. - */ - rc = do_lock(f, LOCKFILE_EXCLUSIVE_LOCK); - if (rc) { - ACR_THROW_IO_IF_ERR(rc); - LeaveCriticalSection(&f->lock); - return -1; - } - /* Set the position to the file end - */ - os.QuadPart = 0; - op.QuadPart = 0; - if (!SetFilePointerEx(f->fd, os, &op, FILE_END)) { - ACR_THROW_IO_ERRNO(); - do_unlock(f); - return -1; - } - f->pos = op.QuadPart; - locked = 1; - } - if (f->blocking == BLK_OFF) { - lpo = &f->overlap; - if (IS_INVALID_HANDLE(lpo->hEvent)) - lpo->hEvent = CreateEvent(NULL, TRUE, TRUE, NULL); - if (IS_INVALID_HANDLE(lpo->hEvent)) { - ACR_THROW_IO_ERRNO(); - if (locked) - do_unlock(f); - return -1; - } - lpo->Offset = (DWORD)(f->pos); - lpo->OffsetHigh = (DWORD)(f->pos >> 32); - } - if (WriteFile(f->fd, &c, 1, &wr, lpo)) { - /* All done. Update the position and return - */ - if (wr) - f->pos += wr; - goto finally; - } - switch (rc = GetLastError()) { - case ERROR_IO_PENDING: - if ((rc = overlapped_wait(f, &wr)) == 0) { - if (wr) { - f->pos += wr; - goto finally; - } - } - break; - default: - break; - } - -finally: - if (locked) - do_unlock(f); - if (wr) - return (jint)wr; - - ACR_DescriptorSetErrEx(_E, f->descriptor, rc); - switch (rc) { - case 0: - case ACR_TIMEUP: - case ERROR_OPERATION_ABORTED: - return 0; - break; - case ERROR_INVALID_HANDLE: - ACR_THROW_EX_IF_ERR(ACR_EX_ACLOSED_DESC, rc); - break; - default: - ACR_THROW_IO_IF_ERR(rc); - break; - } - return -1; -} - -ACR_IO_EXPORT_DECLARE(jint, FileSystemIo, write1)(ACR_JNISTDARGS, - jint file, - jbyteArray buf, - jint off, - jint len) -{ - jbyte *bb; - DWORD rc = 0; - DWORD po = (DWORD)off; - DWORD cs = (DWORD)len; - DWORD wr = 0; - int locked = 0; - LPOVERLAPPED lpo = NULL; - acr_file_t *f = (acr_file_t *)ACR_IOH_FDATA(file); - - if (ACR_IOH_FTYPE(file) != ACR_DT_FILE) { - ACR_THROW_EX_IF_ERR(ACR_EX_INVALID_DESC, ACR_EFTYPE); - return -1; - } - if (IS_INVALID_HANDLE(f)) { - ACR_THROW_EX_IF_ERR(ACR_EX_CLOSED_DESC, ACR_EBADF); - return -1; - } - - if (f->flags & ACR_FOPEN_APPEND) { - LARGE_INTEGER os; - LARGE_INTEGER op; - - EnterCriticalSection(&f->lock); - /* apr_file_lock will mutex the file across processes. - * The call to apr_thread_mutex_lock is added to avoid - * a race condition between LockFile and WriteFile - * that occasionally leads to deadlocked threads. - */ - rc = do_lock(f, LOCKFILE_EXCLUSIVE_LOCK); - if (rc) { - ACR_THROW_IO_IF_ERR(rc); - LeaveCriticalSection(&f->lock); - return -1; - } - /* Set the position to the file end - */ - os.QuadPart = 0; - op.QuadPart = 0; - if (!SetFilePointerEx(f->fd, os, &op, FILE_END)) { - ACR_THROW_IO_ERRNO(); - do_unlock(f); - return -1; - } - f->pos = op.QuadPart; - locked = 1; - } - if (f->blocking == BLK_OFF) { - lpo = &f->overlap; - if (IS_INVALID_HANDLE(lpo->hEvent)) - lpo->hEvent = CreateEvent(NULL, TRUE, TRUE, NULL); - if (IS_INVALID_HANDLE(lpo->hEvent)) { - ACR_THROW_IO_ERRNO(); - if (locked) - do_unlock(f); - return -1; - } - lpo->Offset = (DWORD)(f->pos); - lpo->OffsetHigh = (DWORD)(f->pos >> 32); - } - - bb = (*_E)->GetByteArrayElements(_E, buf, NULL); - if (!bb) { - if (locked) - do_unlock(f); - return -1; - } - if (WriteFile(f->fd, bb + po, cs, &wr, lpo)) { - /* All done. Update the position and return - */ - if (wr) - f->pos += wr; - goto finally; - } - switch (rc = GetLastError()) { - case ERROR_IO_PENDING: - if ((rc = overlapped_wait(f, &wr)) == 0) { - if (wr) { - f->pos += wr; - goto finally; - } - } - break; - default: - break; - } - -finally: - if (locked) - do_unlock(f); - (*_E)->ReleaseByteArrayElements(_E, buf, bb, JNI_ABORT); - if (wr) - return (jint)wr; - - ACR_DescriptorSetErrEx(_E, f->descriptor, rc); - switch (rc) { - case 0: - case ACR_TIMEUP: - case ERROR_OPERATION_ABORTED: - return 0; - break; - case ERROR_INVALID_HANDLE: - ACR_THROW_EX_IF_ERR(ACR_EX_ACLOSED_DESC, rc); - break; - default: - ACR_THROW_IO_IF_ERR(rc); - break; - } - return -1; -} - -ACR_IO_EXPORT_DECLARE(jlong, FileSystemIo, write2)(ACR_JNISTDARGS, - jint file, - jobject ptr, - jlong off, - jlong len) -{ - size_t pl; - jbyte *pb; - DWORD rc = 0; - DWORD po = (DWORD)off; - DWORD cs = (DWORD)len; - DWORD wr = 0; - int locked = 0; - LPOVERLAPPED lpo = NULL; - acr_file_t *f = (acr_file_t *)ACR_IOH_FDATA(file); - - if (ACR_IOH_FTYPE(file) != ACR_DT_FILE) { - ACR_THROW_EX_IF_ERR(ACR_EX_INVALID_DESC, ACR_EFTYPE); - return -1; - } - if (IS_INVALID_HANDLE(f)) { - ACR_THROW_EX_IF_ERR(ACR_EX_CLOSED_DESC, ACR_EBADF); - return -1; - } - if (f->flags & ACR_FOPEN_APPEND) { - LARGE_INTEGER os; - LARGE_INTEGER op; - - EnterCriticalSection(&f->lock); - /* apr_file_lock will mutex the file across processes. - * The call to apr_thread_mutex_lock is added to avoid - * a race condition between LockFile and WriteFile - * that occasionally leads to deadlocked threads. - */ - rc = do_lock(f, LOCKFILE_EXCLUSIVE_LOCK); - if (rc) { - ACR_THROW_IO_IF_ERR(rc); - LeaveCriticalSection(&f->lock); - return -1; - } - /* Set the position to the file end - */ - os.QuadPart = 0; - op.QuadPart = 0; - if (!SetFilePointerEx(f->fd, os, &op, FILE_END)) { - ACR_THROW_IO_ERRNO(); - do_unlock(f); - return -1; - } - f->pos = op.QuadPart; - locked = 1; - } - if (f->blocking == BLK_OFF) { - lpo = &f->overlap; - if (IS_INVALID_HANDLE(lpo->hEvent)) - lpo->hEvent = CreateEvent(NULL, TRUE, TRUE, NULL); - if (IS_INVALID_HANDLE(lpo->hEvent)) { - ACR_THROW_IO_ERRNO(); - if (locked) - do_unlock(f); - return -1; - } - lpo->Offset = (DWORD)(f->pos); - lpo->OffsetHigh = (DWORD)(f->pos >> 32); - } - pb = (jbyte *)ACR_PointerGet(_E, ptr, &pl); - if (!pb) { - ACR_ThrowException(_E, THROW_NMARK, ACR_EX_ENULL, 0); - if (locked) - do_unlock(f); - return -1; - } - if ((po + cs) > (DWORD)pl) { - ACR_ThrowException(_E, THROW_NMARK, ACR_EX_EINDEX, 0); - if (locked) - do_unlock(f); - return -1; - } - - if (WriteFile(f->fd, pb + po, cs, &wr, lpo)) { - /* All done. Update the position and return - */ - if (wr) - f->pos += wr; - goto finally; - } - switch (rc = GetLastError()) { - case ERROR_IO_PENDING: - if ((rc = overlapped_wait(f, &wr)) == 0) { - if (wr) { - f->pos += wr; - goto finally; - } - } - break; - default: - break; - } - -finally: - if (locked) - do_unlock(f); - if (wr) - return (jlong)wr; - - ACR_DescriptorSetErrEx(_E, f->descriptor, rc); - switch (rc) { - case 0: - case ACR_TIMEUP: - case ERROR_OPERATION_ABORTED: - return 0; - break; - case ERROR_INVALID_HANDLE: - ACR_THROW_EX_IF_ERR(ACR_EX_ACLOSED_DESC, rc); - break; - default: - ACR_THROW_IO_IF_ERR(rc); - break; - } - return -1; -} - -ACR_IO_EXPORT_DECLARE(jint, FileSystemIo, write3)(ACR_JNISTDARGS, - jint file, - jobject dbb, - jint off, - jint len) -{ -#if defined(_DEBUG) - DWORD pl; -#endif - jbyte *pb; - DWORD rc = 0; - DWORD po = (DWORD)off; - DWORD cs = (DWORD)len; - DWORD wr = 0; - int locked = 0; - LPOVERLAPPED lpo = NULL; - acr_file_t *f = (acr_file_t *)ACR_IOH_FDATA(file); - - if (ACR_IOH_FTYPE(file) != ACR_DT_FILE) { - ACR_THROW_EX_IF_ERR(ACR_EX_INVALID_DESC, ACR_EFTYPE); - return -1; - } - if (IS_INVALID_HANDLE(f)) { - ACR_THROW_EX_IF_ERR(ACR_EX_CLOSED_DESC, ACR_EBADF); - return -1; - } - if (f->flags & ACR_FOPEN_APPEND) { - LARGE_INTEGER os; - LARGE_INTEGER op; - - EnterCriticalSection(&f->lock); - /* apr_file_lock will mutex the file across processes. - * The call to apr_thread_mutex_lock is added to avoid - * a race condition between LockFile and WriteFile - * that occasionally leads to deadlocked threads. - */ - rc = do_lock(f, LOCKFILE_EXCLUSIVE_LOCK); - if (rc) { - ACR_THROW_IO_IF_ERR(rc); - LeaveCriticalSection(&f->lock); - return -1; - } - /* Set the position to the file end - */ - os.QuadPart = 0; - op.QuadPart = 0; - if (!SetFilePointerEx(f->fd, os, &op, FILE_END)) { - ACR_THROW_IO_ERRNO(); - do_unlock(f); - return -1; - } - f->pos = op.QuadPart; - locked = 1; - } - if (f->blocking == BLK_OFF) { - lpo = &f->overlap; - if (IS_INVALID_HANDLE(lpo->hEvent)) - lpo->hEvent = CreateEvent(NULL, TRUE, TRUE, NULL); - if (IS_INVALID_HANDLE(lpo->hEvent)) { - ACR_THROW_IO_ERRNO(); - if (locked) - do_unlock(f); - return -1; - } - lpo->Offset = (DWORD)(f->pos); - lpo->OffsetHigh = (DWORD)(f->pos >> 32); - } - pb = (jbyte *)(*_E)->GetDirectBufferAddress(_E, dbb); - if (!pb) { - ACR_ThrowException(_E, THROW_NMARK, ACR_EX_ENULL, 0); - if (locked) - do_unlock(f); - return -1; - } -#if defined(_DEBUG) - pl = (DWORD)(*_E)->GetDirectBufferCapacity(_E, dbb); - if ((po + cs) > pl) { - ACR_ThrowException(_E, THROW_NMARK, ACR_EX_EINDEX, 0); - if (locked) - do_unlock(f); - return -1; - } -#endif - if (WriteFile(f->fd, pb + po, cs, &wr, lpo)) { - /* All done. Update the position and return - */ - if (wr) - f->pos += wr; - goto finally; - } - switch (rc = GetLastError()) { - case ERROR_IO_PENDING: - if ((rc = overlapped_wait(f, &wr)) == 0) { - if (wr) { - f->pos += wr; - goto finally; - } - } - break; - default: - break; - } - -finally: - if (locked) - do_unlock(f); - if (wr) - return (jint)wr; - - ACR_DescriptorSetErrEx(_E, f->descriptor, rc); - switch (rc) { - case 0: - case ACR_TIMEUP: - case ERROR_OPERATION_ABORTED: - return 0; - break; - case ERROR_INVALID_HANDLE: - ACR_THROW_EX_IF_ERR(ACR_EX_ACLOSED_DESC, rc); - break; - default: - ACR_THROW_IO_IF_ERR(rc); - break; - } - return -1; -} - -ACR_IO_EXPORT_DECLARE(jlong, FileSystemIo, write4)(ACR_JNISTDARGS, - jint file, - jobjectArray vec, - jint off, - jint len) -{ - DWORD i; - DWORD pl; - DWORD rc = 0; - DWORD wr; - DWORD po = (DWORD)off; - DWORD cs = (DWORD)len; - jbyteArray bae; - jbyte *bab; - DWORD bal; - int locked = 0; - INT64 nbytes = 0; - LPOVERLAPPED lpo = NULL; - acr_file_t *f = (acr_file_t *)ACR_IOH_FDATA(file); - - if (ACR_IOH_FTYPE(file) != ACR_DT_FILE) { - ACR_THROW_EX_IF_ERR(ACR_EX_INVALID_DESC, ACR_EFTYPE); - return -1; - } - if (IS_INVALID_HANDLE(f)) { - ACR_THROW_EX_IF_ERR(ACR_EX_CLOSED_DESC, ACR_EBADF); - return -1; - } - pl = (DWORD)(*_E)->GetArrayLength(_E, vec); - if ((po + cs) > pl) { - ACR_ThrowException(_E, THROW_NMARK, ACR_EX_EINDEX, 0); - return -1; - } - if (f->flags & ACR_FOPEN_APPEND) { - LARGE_INTEGER os; - LARGE_INTEGER op; - - EnterCriticalSection(&f->lock); - /* apr_file_lock will mutex the file across processes. - * The call to apr_thread_mutex_lock is added to avoid - * a race condition between LockFile and WriteFile - * that occasionally leads to deadlocked threads. - */ - rc = do_lock(f, LOCKFILE_EXCLUSIVE_LOCK); - if (rc) { - ACR_THROW_IO_IF_ERR(rc); - LeaveCriticalSection(&f->lock); - return -1; - } - /* Set the position to the file end - */ - os.QuadPart = 0; - op.QuadPart = 0; - if (!SetFilePointerEx(f->fd, os, &op, FILE_END)) { - ACR_THROW_IO_ERRNO(); - do_unlock(f); - return -1; - } - f->pos = op.QuadPart; - locked = 1; - } - if (f->blocking == BLK_OFF) { - lpo = &f->overlap; - if (IS_INVALID_HANDLE(lpo->hEvent)) - lpo->hEvent = CreateEvent(NULL, TRUE, TRUE, NULL); - if (IS_INVALID_HANDLE(lpo->hEvent)) { - ACR_THROW_IO_ERRNO(); - if (locked) - do_unlock(f); - return -1; - } - } - - for (i = 0; i < cs, rc == 0; i++) { - bae = (*_E)->GetObjectArrayElement(_E, vec, (jsize)(i + po)); - bal = (DWORD)(*_E)->GetArrayLength(_E, bae); - bab = (*_E)->GetByteArrayElements(_E, bae, NULL); - if (lpo) { - lpo->Offset = (DWORD)(f->pos); - lpo->OffsetHigh = (DWORD)(f->pos >> 32); - } - wr = 0; - if (WriteFile(f->fd, bab, bal, &wr, lpo)) { - /* All done. Update the position and return - */ - if (wr) { - f->pos += wr; - nbytes += wr; - } - } - else { - switch (rc = GetLastError()) { - case ERROR_IO_PENDING: - if ((rc = overlapped_wait(f, &wr)) == 0) { - if (wr) { - f->pos += wr; - nbytes += wr; - } - } - break; - default: - break; - } - } - (*_E)->ReleaseByteArrayElements(_E, bae, bab, JNI_ABORT); - (*_E)->DeleteLocalRef(_E, bae); - } - - if (locked) - do_unlock(f); - if (nbytes) - return (jlong)nbytes; - - ACR_DescriptorSetErrEx(_E, f->descriptor, rc); - switch (rc) { - case 0: - case ACR_TIMEUP: - return 0; - break; - case ERROR_INVALID_HANDLE: - ACR_THROW_EX_IF_ERR(ACR_EX_ACLOSED_DESC, rc); - break; - default: - ACR_THROW_IO_IF_ERR(rc); - break; - } - return -1; -} - -ACR_IO_EXPORT_DECLARE(jlong, FileSystemIo, write5)(ACR_JNISTDARGS, - jint file, - jobjectArray vec, - jint off, - jint len) -{ - DWORD i; - DWORD pl; - DWORD rc = 0; - DWORD wr; - DWORD po = (DWORD)off; - DWORD cs = (DWORD)len; - jobject bbe; - void *bbb; - DWORD bbl; - int locked = 0; - INT64 nbytes = 0; - LPOVERLAPPED lpo = NULL; - acr_file_t *f = (acr_file_t *)ACR_IOH_FDATA(file); - - if (ACR_IOH_FTYPE(file) != ACR_DT_FILE) { - ACR_THROW_EX_IF_ERR(ACR_EX_INVALID_DESC, ACR_EFTYPE); - return -1; - } - if (IS_INVALID_HANDLE(f)) { - ACR_THROW_EX_IF_ERR(ACR_EX_CLOSED_DESC, ACR_EBADF); - return -1; - } - pl = (DWORD)(*_E)->GetArrayLength(_E, vec); - if ((po + cs) > pl) { - ACR_ThrowException(_E, THROW_NMARK, ACR_EX_EINDEX, 0); - return -1; - } - if (f->flags & ACR_FOPEN_APPEND) { - LARGE_INTEGER os; - LARGE_INTEGER op; - - EnterCriticalSection(&f->lock); - /* apr_file_lock will mutex the file across processes. - * The call to apr_thread_mutex_lock is added to avoid - * a race condition between LockFile and WriteFile - * that occasionally leads to deadlocked threads. - */ - rc = do_lock(f, LOCKFILE_EXCLUSIVE_LOCK); - if (rc) { - ACR_THROW_IO_IF_ERR(rc); - LeaveCriticalSection(&f->lock); - return -1; - } - /* Set the position to the file end - */ - os.QuadPart = 0; - op.QuadPart = 0; - if (!SetFilePointerEx(f->fd, os, &op, FILE_END)) { - ACR_THROW_IO_ERRNO(); - do_unlock(f); - return -1; - } - f->pos = op.QuadPart; - locked = 1; - } - if (f->blocking == BLK_OFF) { - lpo = &f->overlap; - if (IS_INVALID_HANDLE(lpo->hEvent)) - lpo->hEvent = CreateEvent(NULL, TRUE, TRUE, NULL); - if (IS_INVALID_HANDLE(lpo->hEvent)) { - ACR_THROW_IO_ERRNO(); - if (locked) - do_unlock(f); - return -1; - } - } - - for (i = 0; i < cs, rc == 0; i++) { - bbe = (*_E)->GetObjectArrayElement(_E, vec, (jsize)(i + po)); - bbl = (DWORD)(*_E)->GetDirectBufferCapacity(_E, bbe); - bbb = (*_E)->GetDirectBufferAddress(_E, bbe); - (*_E)->DeleteLocalRef(_E, bbe); - - if (lpo) { - lpo->Offset = (DWORD)(f->pos); - lpo->OffsetHigh = (DWORD)(f->pos >> 32); - } - wr = 0; - if (WriteFile(f->fd, bbb, bbl, &wr, lpo)) { - /* All done. Update the position and return - */ - if (wr) { - f->pos += wr; - nbytes += wr; - } - } - else { - switch (rc = GetLastError()) { - case ERROR_IO_PENDING: - if ((rc = overlapped_wait(f, &wr)) == 0) { - if (wr) { - f->pos += wr; - nbytes += wr; - } - } - break; - default: - break; - } - } - } - - if (locked) - do_unlock(f); - if (nbytes) - return (jlong)nbytes; - - ACR_DescriptorSetErrEx(_E, f->descriptor, rc); - switch (rc) { - case 0: - case ACR_TIMEUP: - case ERROR_OPERATION_ABORTED: - return 0; - break; - case ERROR_INVALID_HANDLE: - ACR_THROW_EX_IF_ERR(ACR_EX_ACLOSED_DESC, rc); - break; - default: - ACR_THROW_IO_IF_ERR(rc); - break; - } - return -1; -} - -ACR_IO_EXPORT_DECLARE(jint, FileSystemIo, fullw0)(ACR_JNISTDARGS, - jint file, - jbyteArray buf, - jint off, - jint len) -{ - jbyte *bb; - jbyte *wb; - DWORD rc = 0; - DWORD po = (DWORD)off; - DWORD cs = (DWORD)len; - DWORD wr; - DWORD nbytes = 0; - int locked = 0; - LPOVERLAPPED lpo = NULL; - acr_file_t *f = (acr_file_t *)ACR_IOH_FDATA(file); - - if (ACR_IOH_FTYPE(file) != ACR_DT_FILE) { - ACR_THROW_EX_IF_ERR(ACR_EX_INVALID_DESC, ACR_EFTYPE); - return -1; - } - if (IS_INVALID_HANDLE(f)) { - ACR_THROW_EX_IF_ERR(ACR_EX_CLOSED_DESC, ACR_EBADF); - return -1; - } - if (f->flags & ACR_FOPEN_APPEND) { - LARGE_INTEGER os; - LARGE_INTEGER op; - - EnterCriticalSection(&f->lock); - /* apr_file_lock will mutex the file across processes. - * The call to apr_thread_mutex_lock is added to avoid - * a race condition between LockFile and WriteFile - * that occasionally leads to deadlocked threads. - */ - rc = do_lock(f, LOCKFILE_EXCLUSIVE_LOCK); - if (rc) { - ACR_THROW_IO_IF_ERR(rc); - LeaveCriticalSection(&f->lock); - return -1; - } - /* Set the position to the file end - */ - os.QuadPart = 0; - op.QuadPart = 0; - if (!SetFilePointerEx(f->fd, os, &op, FILE_END)) { - ACR_THROW_IO_ERRNO(); - do_unlock(f); - return -1; - } - f->pos = op.QuadPart; - locked = 1; - } - if (f->blocking == BLK_OFF) { - lpo = &f->overlap; - if (IS_INVALID_HANDLE(lpo->hEvent)) - lpo->hEvent = CreateEvent(NULL, TRUE, TRUE, NULL); - if (IS_INVALID_HANDLE(lpo->hEvent)) { - ACR_THROW_IO_ERRNO(); - if (locked) - do_unlock(f); - return -1; - } - } - bb = (*_E)->GetByteArrayElements(_E, buf, NULL); - if (!bb) { - if (locked) - do_unlock(f); - return -1; - } - wb = bb + po; - do { - if (lpo) { - lpo->Offset = (DWORD)(f->pos); - lpo->OffsetHigh = (DWORD)(f->pos >> 32); - } - wr = 0; - if (WriteFile(f->fd, wb, cs, &wr, lpo)) { - /* All done. Update the position and return - */ - if (wr) { - f->pos += wr; - nbytes += wr; - wb += wr; - cs -= wr; - } - } - else { - switch (rc = GetLastError()) { - case ERROR_IO_PENDING: - if ((rc = overlapped_wait_all(f, &wr)) == 0) { - if (wr) { - f->pos += wr; - nbytes += wr; - wb += wr; - cs -= wr; - } - } - break; - default: - break; - } - } - if (rc && rc != ACR_TIMEUP) - break; - } while (cs > 0); - - if (locked) - do_unlock(f); - (*_E)->ReleaseByteArrayElements(_E, buf, bb, JNI_ABORT); - if (nbytes) - return (jint)nbytes; - - ACR_DescriptorSetErrEx(_E, f->descriptor, rc); - switch (rc) { - case 0: - case ACR_TIMEUP: - return 0; - break; - case ERROR_INVALID_HANDLE: - ACR_THROW_EX_IF_ERR(ACR_EX_ACLOSED_DESC, rc); - break; - default: - ACR_THROW_IO_IF_ERR(rc); - break; - } - return -1; -} - -ACR_IO_EXPORT_DECLARE(jlong, FileSystemIo, fullw1)(ACR_JNISTDARGS, - jint file, - jobject ptr, - jlong off, - jlong len) -{ - size_t pl; - jbyte *pb; - DWORD rc = 0; - DWORD po = (DWORD)off; - DWORD cs = (DWORD)len; - DWORD wr; - DWORD nbytes = 0; - int locked = 0; - LPOVERLAPPED lpo = NULL; - acr_file_t *f = (acr_file_t *)ACR_IOH_FDATA(file); - - if (ACR_IOH_FTYPE(file) != ACR_DT_FILE) { - ACR_THROW_EX_IF_ERR(ACR_EX_INVALID_DESC, ACR_EFTYPE); - return -1; - } - if (IS_INVALID_HANDLE(f)) { - ACR_THROW_EX_IF_ERR(ACR_EX_CLOSED_DESC, ACR_EBADF); - return -1; - } - pb = (jbyte *)ACR_PointerGet(_E, ptr, &pl); - if (!pb) { - ACR_ThrowException(_E, THROW_NMARK, ACR_EX_ENULL, 0); - return -1; - } - if ((po + cs) > (DWORD)pl) { - ACR_ThrowException(_E, THROW_NMARK, ACR_EX_EINDEX, 0); - return -1; - } - pb = pb + po; - if (f->flags & ACR_FOPEN_APPEND) { - LARGE_INTEGER os; - LARGE_INTEGER op; - - EnterCriticalSection(&f->lock); - /* apr_file_lock will mutex the file across processes. - * The call to apr_thread_mutex_lock is added to avoid - * a race condition between LockFile and WriteFile - * that occasionally leads to deadlocked threads. - */ - rc = do_lock(f, LOCKFILE_EXCLUSIVE_LOCK); - if (rc) { - ACR_THROW_IO_IF_ERR(rc); - LeaveCriticalSection(&f->lock); - return -1; - } - /* Set the position to the file end - */ - os.QuadPart = 0; - op.QuadPart = 0; - if (!SetFilePointerEx(f->fd, os, &op, FILE_END)) { - ACR_THROW_IO_ERRNO(); - do_unlock(f); - return -1; - } - f->pos = op.QuadPart; - locked = 1; - } - if (f->blocking == BLK_OFF) { - lpo = &f->overlap; - if (IS_INVALID_HANDLE(lpo->hEvent)) - lpo->hEvent = CreateEvent(NULL, TRUE, TRUE, NULL); - if (IS_INVALID_HANDLE(lpo->hEvent)) { - ACR_THROW_IO_ERRNO(); - if (locked) - do_unlock(f); - return -1; - } - } - - do { - if (lpo) { - lpo->Offset = (DWORD)(f->pos); - lpo->OffsetHigh = (DWORD)(f->pos >> 32); - } - wr = 0; - if (WriteFile(f->fd, pb, cs, &wr, lpo)) { - /* All done. Update the position and return - */ - if (wr) { - f->pos += wr; - nbytes += wr; - pb += wr; - cs -= wr; - } - } - else { - switch (rc = GetLastError()) { - case ERROR_IO_PENDING: - if ((rc = overlapped_wait_all(f, &wr)) == 0) { - if (wr) { - f->pos += wr; - nbytes += wr; - pb += wr; - cs -= wr; - } - } - break; - default: - break; - } - } - if (rc && rc != ACR_TIMEUP) - break; - } while (cs > 0); - - if (locked) - do_unlock(f); - if (nbytes) - return (jlong)nbytes; - - ACR_DescriptorSetErrEx(_E, f->descriptor, rc); - switch (rc) { - case 0: - case ACR_TIMEUP: - case ERROR_OPERATION_ABORTED: - return 0; - break; - case ERROR_INVALID_HANDLE: - ACR_THROW_EX_IF_ERR(ACR_EX_ACLOSED_DESC, rc); - break; - default: - ACR_THROW_IO_IF_ERR(rc); - break; - } - return -1; -} - -ACR_IO_EXPORT_DECLARE(jint, FileSystemIo, fullw2)(ACR_JNISTDARGS, - jint file, - jobject dbb, - jint off, - jint len) -{ -#if defined(_DEBUG) - DWORD pl; -#endif - jbyte *pb; - DWORD rc = 0; - DWORD po = (DWORD)off; - DWORD cs = (DWORD)len; - DWORD wr; - DWORD nbytes = 0; - int locked = 0; - LPOVERLAPPED lpo = NULL; - acr_file_t *f = (acr_file_t *)ACR_IOH_FDATA(file); - - if (ACR_IOH_FTYPE(file) != ACR_DT_FILE) { - ACR_THROW_EX_IF_ERR(ACR_EX_INVALID_DESC, ACR_EFTYPE); - return -1; - } - if (IS_INVALID_HANDLE(f)) { - ACR_THROW_EX_IF_ERR(ACR_EX_CLOSED_DESC, ACR_EBADF); - return -1; - } - pb = (jbyte *)(*_E)->GetDirectBufferAddress(_E, dbb); - if (!pb) { - ACR_ThrowException(_E, THROW_NMARK, ACR_EX_ENULL, 0); - return -1; - } -#if defined(_DEBUG) - pl = (DWORD)(*_E)->GetDirectBufferCapacity(_E, dbb); - if ((po + cs) > pl) { - ACR_ThrowException(_E, THROW_NMARK, ACR_EX_EINDEX, 0); - return -1; - } -#endif - pb = pb + po; - if (f->flags & ACR_FOPEN_APPEND) { - LARGE_INTEGER os; - LARGE_INTEGER op; - - EnterCriticalSection(&f->lock); - /* apr_file_lock will mutex the file across processes. - * The call to apr_thread_mutex_lock is added to avoid - * a race condition between LockFile and WriteFile - * that occasionally leads to deadlocked threads. - */ - rc = do_lock(f, LOCKFILE_EXCLUSIVE_LOCK); - if (rc) { - ACR_THROW_IO_IF_ERR(rc); - LeaveCriticalSection(&f->lock); - return -1; - } - /* Set the position to the file end - */ - os.QuadPart = 0; - op.QuadPart = 0; - if (!SetFilePointerEx(f->fd, os, &op, FILE_END)) { - ACR_THROW_IO_ERRNO(); - do_unlock(f); - return -1; - } - f->pos = op.QuadPart; - locked = 1; - } - if (f->blocking == BLK_OFF) { - lpo = &f->overlap; - if (IS_INVALID_HANDLE(lpo->hEvent)) - lpo->hEvent = CreateEvent(NULL, TRUE, TRUE, NULL); - if (IS_INVALID_HANDLE(lpo->hEvent)) { - ACR_THROW_IO_ERRNO(); - if (locked) - do_unlock(f); - return -1; - } - } - - do { - if (lpo) { - lpo->Offset = (DWORD)(f->pos); - lpo->OffsetHigh = (DWORD)(f->pos >> 32); - } - wr = 0; - if (WriteFile(f->fd, pb, cs, &wr, lpo)) { - /* All done. Update the position and return - */ - if (wr) { - f->pos += wr; - nbytes += wr; - pb += wr; - cs -= wr; - } - } - else { - switch (rc = GetLastError()) { - case ERROR_IO_PENDING: - if ((rc = overlapped_wait_all(f, &wr)) == 0) { - if (wr) { - f->pos += wr; - nbytes += wr; - pb += wr; - cs -= wr; - } - } - break; - default: - break; - } - } - if (rc && rc != ACR_TIMEUP) - break; - } while (cs > 0); - - if (locked) - do_unlock(f); - if (nbytes) - return (jint)nbytes; - - ACR_DescriptorSetErrEx(_E, f->descriptor, rc); - switch (rc) { - case 0: - case ACR_TIMEUP: - case ERROR_OPERATION_ABORTED: - return 0; - break; - case ERROR_INVALID_HANDLE: - ACR_THROW_EX_IF_ERR(ACR_EX_ACLOSED_DESC, rc); - break; - default: - ACR_THROW_IO_IF_ERR(rc); - break; - } - return -1; -}
