Beispiel #1
0
/*
** Acquire a reader lock.
*/
static int getReadLock( os2File *pFile ){
  FILELOCK  LockArea,
            UnlockArea;
  APIRET res;
  memset(&LockArea, 0, sizeof(LockArea));
  memset(&UnlockArea, 0, sizeof(UnlockArea));
  LockArea.lOffset = SHARED_FIRST;
  LockArea.lRange = SHARED_SIZE;
  UnlockArea.lOffset = 0L;
  UnlockArea.lRange = 0L;
  res = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, 2000L, 1L );
  OSTRACE3( "GETREADLOCK %d res=%d\n", pFile->h, res );
  return res;
}
Beispiel #2
0
/*
** Undo a readlock
*/
static int unlockReadLock( os2File *id ){
  FILELOCK  LockArea,
            UnlockArea;
  APIRET res;
  memset(&LockArea, 0, sizeof(LockArea));
  memset(&UnlockArea, 0, sizeof(UnlockArea));
  LockArea.lOffset = 0L;
  LockArea.lRange = 0L;
  UnlockArea.lOffset = SHARED_FIRST;
  UnlockArea.lRange = SHARED_SIZE;
  res = DosSetFileLocks( id->h, &UnlockArea, &LockArea, 2000L, 1L );
  OSTRACE3( "UNLOCK-READLOCK file handle=%d res=%d?\n", id->h, res );
  return res;
}
Beispiel #3
0
int flock(int handle, int mode)
{
	FILELOCK slock, sunlock;
	APIRET r;

	slock.lOffset = sunlock.lOffset = 0;
	if (mode & LOCK_UN) {
		sunlock.lRange = 0x7fffffff;
		slock.lRange = 0;
	} else {
		slock.lRange = 0x7fffffff;
		sunlock.lRange = 0;
	}
	r = DosSetFileLocks(handle, &sunlock, &slock, 
	             (mode & LOCK_NB) ? 0 : 10000, (mode & LOCK_SH) ? 1 : 0);
	if (r) errno = EWOULDBLOCK;
	return r ? -1 : 0;
}
Beispiel #4
0
PRStatus
_PR_MD_LOCKFILE(PRInt32 f)
{
    PRInt32   rv;
    FILELOCK lock, unlock;
    FILELOCKL lockL, unlockL;
    
    lock.lOffset = 0;
    lockL.lOffset = 0;
    lock.lRange = 0xffffffff;
    lockL.lRange =  0xffffffffffffffff;
    unlock.lOffset = 0;
    unlock.lRange = 0;
    unlockL.lOffset = 0;
    unlockL.lRange = 0;

    /*
     * loop trying to DosSetFileLocks(),
     * pause for a few miliseconds when can't get the lock
     * and try again
     */
    for( rv = FALSE; rv == FALSE; /* do nothing */ )
    {
        if (isWSEB)
        {
	    rv = myDosSetFileLocksL( (HFILE) f,
			                    &unlockL, &lockL,
			                    0, 0);
        }
        else
        {
	    rv = DosSetFileLocks( (HFILE) f,
			                    &unlock, &lock,
			                    0, 0);
        }
		if ( rv != NO_ERROR )
        {
            DosSleep( 50 );  /* Sleep() a few milisecs and try again. */
        }            
    } /* end for() */
    return PR_SUCCESS;
} /* end _PR_MD_LOCKFILE() */
Beispiel #5
0
PRStatus
_PR_MD_UNLOCKFILE(PRInt32 f)
{
    PRInt32   rv;
    FILELOCK lock, unlock;
    FILELOCKL lockL, unlockL;
    
    lock.lOffset = 0;
    lockL.lOffset = 0;
    lock.lRange = 0;
    lockL.lRange = 0;
    unlock.lOffset = 0;
    unlockL.lOffset = 0;
    unlock.lRange = 0xffffffff;
    unlockL.lRange = 0xffffffffffffffff;
    
    if (isWSEB)
    {
        rv = myDosSetFileLocksL( (HFILE) f,
                                        &unlockL, &lockL,
                                        0, 0);
    }
    else
    {
        rv = DosSetFileLocks( (HFILE) f,
                                    &unlock, &lock,
                                    0, 0);
    }
            
    if ( rv != NO_ERROR )
    {
        return PR_SUCCESS;
    }
    else
    {
        return PR_FAILURE;
    }
} /* end _PR_MD_UNLOCKFILE() */
Beispiel #6
0
inline APIRET _SetFileLocksL(HFILE hFile,
			     PFILELOCKL pflUnlock,
			     PFILELOCKL pflLock,
			     ULONG timeout,
			     ULONG flags)
{
  if (_DosSetFileLocksL)
  {
    APIRET rc;
    rc = _DosSetFileLocksL( hFile, pflUnlock, pflLock, timeout, flags);

    /*
      on FAT/HPFS/LAN a INVALID_PARAMETER is returned, seems that
      only JFS can handle >2GB ranges.
    */
    if (rc != 87)
      return rc;
    /* got INVALID_PARAMETER, fallback to standard call */
  }

  FILELOCK flUnlock = { pflUnlock->lOffset, pflUnlock->lRange };
  FILELOCK flLock = { pflLock->lOffset, pflLock->lRange };
  return DosSetFileLocks( hFile, &flUnlock, &flLock, timeout, flags);
}
/*
** Lock the file with the lock specified by parameter locktype - one
** of the following:
**
**     (1) SHARED_LOCK
**     (2) RESERVED_LOCK
**     (3) PENDING_LOCK
**     (4) EXCLUSIVE_LOCK
**
** Sometimes when requesting one lock state, additional lock states
** are inserted in between.  The locking might fail on one of the later
** transitions leaving the lock state different from what it started but
** still short of its goal.  The following chart shows the allowed
** transitions and the inserted intermediate states:
**
**    UNLOCKED -> SHARED
**    SHARED -> RESERVED
**    SHARED -> (PENDING) -> EXCLUSIVE
**    RESERVED -> (PENDING) -> EXCLUSIVE
**    PENDING -> EXCLUSIVE
**
** This routine will only increase a lock.  The os2Unlock() routine
** erases all locks at once and returns us immediately to locking level 0.
** It is not possible to lower the locking level one step at a time.  You
** must go straight to locking level 0.
*/
static int os2Lock( sqlite3_file *id, int locktype ){
  int rc = SQLITE_OK;       /* Return code from subroutines */
  APIRET res = NO_ERROR;    /* Result of an OS/2 lock call */
  int newLocktype;       /* Set pFile->locktype to this value before exiting */
  int gotPendingLock = 0;/* True if we acquired a PENDING lock this time */
  FILELOCK  LockArea,
            UnlockArea;
  os2File *pFile = (os2File*)id;
  memset(&LockArea, 0, sizeof(LockArea));
  memset(&UnlockArea, 0, sizeof(UnlockArea));
  assert( pFile!=0 );
  OSTRACE4( "LOCK %d %d was %d\n", pFile->h, locktype, pFile->locktype );

  /* If there is already a lock of this type or more restrictive on the
  ** os2File, do nothing. Don't use the end_lock: exit path, as
  ** sqlite3_mutex_enter() hasn't been called yet.
  */
  if( pFile->locktype>=locktype ){
    OSTRACE3( "LOCK %d %d ok (already held)\n", pFile->h, locktype );
    return SQLITE_OK;
  }

  /* Make sure the locking sequence is correct
  */
  assert( pFile->locktype!=NO_LOCK || locktype==SHARED_LOCK );
  assert( locktype!=PENDING_LOCK );
  assert( locktype!=RESERVED_LOCK || pFile->locktype==SHARED_LOCK );

  /* Lock the PENDING_LOCK byte if we need to acquire a PENDING lock or
  ** a SHARED lock.  If we are acquiring a SHARED lock, the acquisition of
  ** the PENDING_LOCK byte is temporary.
  */
  newLocktype = pFile->locktype;
  if( pFile->locktype==NO_LOCK
      || (locktype==EXCLUSIVE_LOCK && pFile->locktype==RESERVED_LOCK)
  ){
    LockArea.lOffset = PENDING_BYTE;
    LockArea.lRange = 1L;
    UnlockArea.lOffset = 0L;
    UnlockArea.lRange = 0L;

    /* wait longer than LOCK_TIMEOUT here not to have to try multiple times */
    res = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, 100L, 0L );
    if( res == NO_ERROR ){
      gotPendingLock = 1;
      OSTRACE3( "LOCK %d pending lock boolean set.  res=%d\n", pFile->h, res );
    }
  }

  /* Acquire a shared lock
  */
  if( locktype==SHARED_LOCK && res == NO_ERROR ){
    assert( pFile->locktype==NO_LOCK );
    res = getReadLock(pFile);
    if( res == NO_ERROR ){
      newLocktype = SHARED_LOCK;
    }
    OSTRACE3( "LOCK %d acquire shared lock. res=%d\n", pFile->h, res );
  }

  /* Acquire a RESERVED lock
  */
  if( locktype==RESERVED_LOCK && res == NO_ERROR ){
    assert( pFile->locktype==SHARED_LOCK );
    LockArea.lOffset = RESERVED_BYTE;
    LockArea.lRange = 1L;
    UnlockArea.lOffset = 0L;
    UnlockArea.lRange = 0L;
    res = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, LOCK_TIMEOUT, 0L );
    if( res == NO_ERROR ){
      newLocktype = RESERVED_LOCK;
    }
    OSTRACE3( "LOCK %d acquire reserved lock. res=%d\n", pFile->h, res );
  }

  /* Acquire a PENDING lock
  */
  if( locktype==EXCLUSIVE_LOCK && res == NO_ERROR ){
    newLocktype = PENDING_LOCK;
    gotPendingLock = 0;
    OSTRACE2( "LOCK %d acquire pending lock. pending lock boolean unset.\n", pFile->h );
  }

  /* Acquire an EXCLUSIVE lock
  */
  if( locktype==EXCLUSIVE_LOCK && res == NO_ERROR ){
    assert( pFile->locktype>=SHARED_LOCK );
    res = unlockReadLock(pFile);
    OSTRACE2( "unreadlock = %d\n", res );
    LockArea.lOffset = SHARED_FIRST;
    LockArea.lRange = SHARED_SIZE;
    UnlockArea.lOffset = 0L;
    UnlockArea.lRange = 0L;
    res = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, LOCK_TIMEOUT, 0L );
    if( res == NO_ERROR ){
      newLocktype = EXCLUSIVE_LOCK;
    }else{
      OSTRACE2( "OS/2 error-code = %d\n", res );
      getReadLock(pFile);
    }
    OSTRACE3( "LOCK %d acquire exclusive lock.  res=%d\n", pFile->h, res );
  }

  /* If we are holding a PENDING lock that ought to be released, then
  ** release it now.
  */
  if( gotPendingLock && locktype==SHARED_LOCK ){
    int r;
    LockArea.lOffset = 0L;
    LockArea.lRange = 0L;
    UnlockArea.lOffset = PENDING_BYTE;
    UnlockArea.lRange = 1L;
    r = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, LOCK_TIMEOUT, 0L );
    OSTRACE3( "LOCK %d unlocking pending/is shared. r=%d\n", pFile->h, r );
  }

  /* Update the state of the lock has held in the file descriptor then
  ** return the appropriate result code.
  */
  if( res == NO_ERROR ){
    rc = SQLITE_OK;
  }else{
    OSTRACE4( "LOCK FAILED %d trying for %d but got %d\n", pFile->h,
              locktype, newLocktype );
    rc = SQLITE_BUSY;
  }
  pFile->locktype = newLocktype;
  OSTRACE3( "LOCK %d now %d\n", pFile->h, pFile->locktype );
  return rc;
}
Beispiel #8
0
APR_DECLARE(apr_status_t) apr_file_write(apr_file_t *thefile, const void *buf, apr_size_t *nbytes)
{
    ULONG rc = 0;
    ULONG byteswritten;

    if (!thefile->isopen) {
        *nbytes = 0;
        return APR_EBADF;
    }

    if (thefile->buffered) {
        char *pos = (char *)buf;
        int blocksize;
        int size = *nbytes;

        apr_thread_mutex_lock(thefile->mutex);

        if ( thefile->direction == 0 ) {
            // Position file pointer for writing at the offset we are logically reading from
            ULONG offset = thefile->filePtr - thefile->dataRead + thefile->bufpos;
            if (offset != thefile->filePtr)
                DosSetFilePtr(thefile->filedes, offset, FILE_BEGIN, &thefile->filePtr );
            thefile->bufpos = thefile->dataRead = 0;
            thefile->direction = 1;
        }

        while (rc == 0 && size > 0) {
            if (thefile->bufpos == thefile->bufsize)   // write buffer is full
                /* XXX bug; - rc is double-transformed os->apr below */
                rc = apr_file_flush(thefile);

            blocksize = size > thefile->bufsize - thefile->bufpos ? thefile->bufsize - thefile->bufpos : size;
            memcpy(thefile->buffer + thefile->bufpos, pos, blocksize);
            thefile->bufpos += blocksize;
            pos += blocksize;
            size -= blocksize;
        }

        apr_thread_mutex_unlock(thefile->mutex);
        return APR_FROM_OS_ERROR(rc);
    } else {
        if (thefile->flags & APR_APPEND) {
            FILELOCK all = { 0, 0x7fffffff };
            ULONG newpos;
            rc = DosSetFileLocks(thefile->filedes, NULL, &all, -1, 0);

            if (rc == 0) {
                rc = DosSetFilePtr(thefile->filedes, 0, FILE_END, &newpos);

                if (rc == 0) {
                    rc = DosWrite(thefile->filedes, buf, *nbytes, &byteswritten);
                }

                DosSetFileLocks(thefile->filedes, &all, NULL, -1, 0);
            }
        } else {
            rc = DosWrite(thefile->filedes, buf, *nbytes, &byteswritten);
        }

        if (rc) {
            *nbytes = 0;
            return APR_FROM_OS_ERROR(rc);
        }

        *nbytes = byteswritten;
        return APR_SUCCESS;
    }
}