You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by mt...@apache.org on 2009/11/24 19:47:16 UTC
svn commit: r883810 [2/3] - in
/commons/sandbox/runtime/trunk/src/main/native: Makefile.in Makefile.msc.in
include/arch/unix/acr_arch.h os/unix/fsysio.c os/unix/fsysrw.c
os/win32/fsysio.c os/win32/fsysrw.c
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;
-}