void CInterProcessLock::Unlock()
{
    if (m_Handle == kInvalidLockHandle) {
        NCBI_THROW(CInterProcessLockException, eNotLocked,
                   "Attempt to unlock not-yet-acquired lock");
    }
    CFastMutexGuard LOCK(s_ProcessLock);

    // Check that lock with specified name not already locked
    // in the current process.
    TLocks::iterator it = s_Locks->find(m_SystemName);
    _VERIFY(it != s_Locks->end());

    if ( it->second > 1 ) {
        // Just decrease reference counter
        it->second--;
        return;
    }

    // Release lock

#if defined(NCBI_OS_UNIX)

#  if defined(F_TLOCK)
    int res = lockf(m_Handle, F_ULOCK, 0);
#  elif defined(F_SETLK)
    struct flock lockparam;
    lockparam.l_type   = F_UNLCK;
    lockparam.l_whence = SEEK_SET;
    lockparam.l_start  = 0;
    lockparam.l_len    = 0;  /* whole file */
    int res = fcntl(m_Handle, F_SETLK, &lockparam);
#  else
#   error "No supported lock method.  Please port this code."
#  endif
    if ( res < 0 ) {
        NCBI_THROW(CInterProcessLockException, eUnlockError,
                   "Cannot release the lock");
    }
    close(m_Handle);
    
#elif defined(NCBI_OS_MSWIN)
    if ( !::ReleaseMutex(m_Handle) ) {
        NCBI_THROW(CInterProcessLockException, eUnlockError,
                   "Cannot release the lock");
    }
    ::CloseHandle(m_Handle);
#endif
    m_Handle = kInvalidLockHandle;
    s_Locks->erase(m_SystemName);
}