Ticket #4363: 4363.patch

File 4363.patch, 11.6 KB (added by pcapriotti, 3 years ago)
  • includes/rts/FileLock.h

    From 577338c2d4857aea6b27b311ba3dd8c202f630f6 Mon Sep 17 00:00:00 2001
    From: Paolo Capriotti <[email protected]>
    Date: Fri, 27 Apr 2012 13:10:33 +0100
    Subject: [PATCH] Enable FileLock for win32 (#4363)
    
    Use 64 bit words as keys for the fd lock map.
    ---
     includes/rts/FileLock.h |    6 +-
     rts/FileLock.c          |  144 ++++++++++++++++++++++++++++++++++++++++++++++
     rts/FileLock.h          |   15 +++++
     rts/Linker.c            |    4 +-
     rts/RtsStartup.c        |    6 +--
     rts/posix/FileLock.c    |  145 -----------------------------------------------
     rts/posix/FileLock.h    |   15 -----
     7 files changed, 164 insertions(+), 171 deletions(-)
     create mode 100644 rts/FileLock.c
     create mode 100644 rts/FileLock.h
     delete mode 100644 rts/posix/FileLock.c
     delete mode 100644 rts/posix/FileLock.h
    
    diff --git a/includes/rts/FileLock.h b/includes/rts/FileLock.h
    index a7d8d3c..e863883 100644
    a b  
    1414#ifndef RTS_FILELOCK_H
    1515#define RTS_FILELOCK_H
    1616
    17 #ifdef HAVE_SYS_TYPES_H
    18 #include <sys/types.h>
    19 #endif
     17#include "Stg.h"
    2018
    21 int  lockFile(int fd, dev_t dev, ino_t ino, int for_writing);
     19int  lockFile(int fd, StgWord64 dev, StgWord64 ino, int for_writing);
    2220int  unlockFile(int fd);
    2321
    2422#endif /* RTS_FILELOCK_H */
  • new file rts/FileLock.c

    diff --git a/rts/FileLock.c b/rts/FileLock.c
    new file mode 100644
    index 0000000..44ff671
    - +  
     1/* -----------------------------------------------------------------------------
     2 *
     3 * (c) The GHC Team, 2007
     4 *
     5 * File locking support as required by Haskell
     6 *
     7 * ---------------------------------------------------------------------------*/
     8 
     9#include "PosixSource.h"
     10#include "Rts.h"
     11
     12#include "FileLock.h"
     13#include "Hash.h"
     14#include "RtsUtils.h"
     15
     16#include <sys/types.h>
     17#include <unistd.h>
     18#include <errno.h>
     19
     20typedef struct {
     21    StgWord64 device;
     22    StgWord64 inode;
     23    int   readers; // >0 : readers,  <0 : writers
     24} Lock;
     25
     26// Two hash tables.  The first maps objects (device/inode pairs) to
     27// Lock objects containing the number of active readers or writers.  The
     28// second maps file descriptors to lock objects, so that we can unlock
     29// by FD without needing to fstat() again.
     30static HashTable *obj_hash;
     31static HashTable *fd_hash;
     32
     33#ifdef THREADED_RTS
     34static Mutex file_lock_mutex;
     35#endif
     36
     37static int cmpLocks(StgWord w1, StgWord w2)
     38{
     39    Lock *l1 = (Lock *)w1;
     40    Lock *l2 = (Lock *)w2;
     41    return (l1->device == l2->device && l1->inode == l2->inode);
     42}
     43
     44static int hashLock(HashTable *table, StgWord w)
     45{
     46    Lock *l = (Lock *)w;
     47    // Just xor all 32-bit words of inode and device, hope this is good enough.
     48    return hashWord(table, l->inode ^ (l->inode >> 32) ^ l->device ^ (l->device >> 32));
     49}
     50
     51void
     52initFileLocking(void)
     53{
     54    obj_hash = allocHashTable_(hashLock, cmpLocks);
     55    fd_hash  = allocHashTable(); /* ordinary word-based table */
     56#ifdef THREADED_RTS
     57    initMutex(&file_lock_mutex);
     58#endif
     59}
     60
     61static void
     62freeLock(void *lock)
     63{
     64    stgFree(lock);
     65}
     66
     67void
     68freeFileLocking(void)
     69{
     70    freeHashTable(obj_hash, freeLock);
     71    freeHashTable(fd_hash,  NULL);
     72#ifdef THREADED_RTS
     73    closeMutex(&file_lock_mutex);
     74#endif
     75}
     76
     77int
     78lockFile(int fd, StgWord64 dev, StgWord64 ino, int for_writing)
     79{
     80    Lock key, *lock;
     81
     82    ACQUIRE_LOCK(&file_lock_mutex);
     83
     84    key.device = dev;
     85    key.inode  = ino;
     86
     87    lock = lookupHashTable(obj_hash, (StgWord)&key);
     88
     89    if (lock == NULL)
     90    {
     91        lock = stgMallocBytes(sizeof(Lock), "lockFile");
     92        lock->device = dev;
     93        lock->inode  = ino;
     94        lock->readers = for_writing ? -1 : 1;
     95        insertHashTable(obj_hash, (StgWord)lock, (void *)lock);
     96        insertHashTable(fd_hash, fd, lock);
     97        RELEASE_LOCK(&file_lock_mutex);
     98        return 0;
     99    }
     100    else
     101    {
     102        // single-writer/multi-reader locking:
     103        if (for_writing || lock->readers < 0) {
     104            RELEASE_LOCK(&file_lock_mutex);
     105            return -1;
     106        }
     107        insertHashTable(fd_hash, fd, lock);
     108        lock->readers++;
     109        RELEASE_LOCK(&file_lock_mutex);
     110        return 0;
     111    }
     112}
     113
     114int
     115unlockFile(int fd)
     116{
     117    Lock *lock;
     118
     119    ACQUIRE_LOCK(&file_lock_mutex);
     120
     121    lock = lookupHashTable(fd_hash, fd);
     122    if (lock == NULL) {
     123        // errorBelch("unlockFile: fd %d not found", fd);
     124        // This is normal: we didn't know when calling unlockFile
     125        // whether this FD referred to a locked file or not.
     126        RELEASE_LOCK(&file_lock_mutex);
     127        return 1;
     128    }
     129
     130    if (lock->readers < 0) {
     131        lock->readers++;
     132    } else {
     133        lock->readers--;
     134    }
     135
     136    if (lock->readers == 0) {
     137        removeHashTable(obj_hash, (StgWord)lock, NULL);
     138        stgFree(lock);
     139    }
     140    removeHashTable(fd_hash, fd, NULL);
     141
     142    RELEASE_LOCK(&file_lock_mutex);
     143    return 0;
     144}
  • new file rts/FileLock.h

    diff --git a/rts/FileLock.h b/rts/FileLock.h
    new file mode 100644
    index 0000000..72ab170
    - +  
     1/* -----------------------------------------------------------------------------
     2 *
     3 * (c) The GHC Team, 2007
     4 *
     5 * File locking support as required by Haskell
     6 *
     7 * ---------------------------------------------------------------------------*/
     8
     9#ifndef POSIX_FILELOCK_H
     10#define POSIX_FILELOCK_H
     11
     12RTS_PRIVATE void initFileLocking(void);
     13RTS_PRIVATE void freeFileLocking(void);
     14
     15#endif /* POSIX_FILELOCK_H */
  • rts/Linker.c

    diff --git a/rts/Linker.c b/rts/Linker.c
    index c983403..57e36d0 100644
    a b typedef struct _RtsSymbolVal { 
    303303      SymI_HasProto(__hscore_get_saved_termios) \
    304304      SymI_HasProto(__hscore_set_saved_termios) \
    305305      SymI_HasProto(shutdownHaskellAndSignal)   \
    306       SymI_HasProto(lockFile)                   \
    307       SymI_HasProto(unlockFile)                 \
    308306      SymI_HasProto(signal_handlers)            \
    309307      SymI_HasProto(stg_sig_install)            \
    310308      SymI_HasProto(rtsTimerSignal)             \
    typedef struct _RtsSymbolVal { 
    10461044      SymI_HasProto(n_capabilities)                     \
    10471045      SymI_HasProto(stg_traceCcszh)                     \
    10481046      SymI_HasProto(stg_traceEventzh)                   \
     1047      SymI_HasProto(lockFile)                           \
     1048      SymI_HasProto(unlockFile)                         \
    10491049      RTS_USER_SIGNALS_SYMBOLS                          \
    10501050      RTS_INTCHAR_SYMBOLS
    10511051
  • rts/RtsStartup.c

    diff --git a/rts/RtsStartup.c b/rts/RtsStartup.c
    index 4b9f6ba..34bcc85 100644
    a b  
    3535#include "Profiling.h"
    3636#include "Timer.h"
    3737#include "Globals.h"
     38#include "FileLock.h"
    3839void exitLinker( void );        // there is no Linker.h file to include
    3940
    4041#if defined(RTS_GTK_FRONTPANEL)
    void exitLinker( void ); // there is no Linker.h file to include 
    5253
    5354#if !defined(mingw32_HOST_OS)
    5455#include "posix/TTY.h"
    55 #include "posix/FileLock.h"
    5656#endif
    5757
    5858#ifdef HAVE_UNISTD_H
    hs_init_ghc(int *argc, char **argv[], RtsConfig rts_config) 
    205205    initGlobalStore();
    206206
    207207    /* initialise file locking, if necessary */
    208 #if !defined(mingw32_HOST_OS)   
    209208    initFileLocking();
    210 #endif
    211209
    212210#if defined(DEBUG)
    213211    /* initialise thread label table (tso->char*) */
    hs_exit_(rtsBool wait_foreign) 
    366364    exitLinker();
    367365
    368366    /* free file locking tables, if necessary */
    369 #if !defined(mingw32_HOST_OS)   
    370367    freeFileLocking();
    371 #endif
    372368
    373369    /* free the stable pointer table */
    374370    exitStablePtrTable();
  • deleted file rts/posix/FileLock.c

    diff --git a/rts/posix/FileLock.c b/rts/posix/FileLock.c
    deleted file mode 100644
    index cb36366..0000000
    + -  
    1 /* -----------------------------------------------------------------------------
    2  *
    3  * (c) The GHC Team, 2007
    4  *
    5  * File locking support as required by Haskell
    6  *
    7  * ---------------------------------------------------------------------------*/
    8  
    9 #include "PosixSource.h"
    10 #include "Rts.h"
    11 
    12 #include "FileLock.h"
    13 #include "Hash.h"
    14 #include "RtsUtils.h"
    15 
    16 #include <sys/types.h>
    17 #include <sys/stat.h>
    18 #include <unistd.h>
    19 #include <errno.h>
    20 
    21 typedef struct {
    22     dev_t device;
    23     ino_t inode;
    24     int   readers; // >0 : readers,  <0 : writers
    25 } Lock;
    26 
    27 // Two hash tables.  The first maps objects (device/inode pairs) to
    28 // Lock objects containing the number of active readers or writers.  The
    29 // second maps file descriptors to lock objects, so that we can unlock
    30 // by FD without needing to fstat() again.
    31 static HashTable *obj_hash;
    32 static HashTable *fd_hash;
    33 
    34 #ifdef THREADED_RTS
    35 static Mutex file_lock_mutex;
    36 #endif
    37 
    38 static int cmpLocks(StgWord w1, StgWord w2)
    39 {
    40     Lock *l1 = (Lock *)w1;
    41     Lock *l2 = (Lock *)w2;
    42     return (l1->device == l2->device && l1->inode == l2->inode);
    43 }
    44 
    45 static int hashLock(HashTable *table, StgWord w)
    46 {
    47     Lock *l = (Lock *)w;
    48     // Just xor the dev_t with the ino_t, hope this is good enough.
    49     return hashWord(table, (StgWord)l->inode ^ (StgWord)l->device);
    50 }
    51 
    52 void
    53 initFileLocking(void)
    54 {
    55     obj_hash = allocHashTable_(hashLock, cmpLocks);
    56     fd_hash  = allocHashTable(); /* ordinary word-based table */
    57 #ifdef THREADED_RTS
    58     initMutex(&file_lock_mutex);
    59 #endif
    60 }
    61 
    62 static void
    63 freeLock(void *lock)
    64 {
    65     stgFree(lock);
    66 }
    67 
    68 void
    69 freeFileLocking(void)
    70 {
    71     freeHashTable(obj_hash, freeLock);
    72     freeHashTable(fd_hash,  NULL);
    73 #ifdef THREADED_RTS
    74     closeMutex(&file_lock_mutex);
    75 #endif
    76 }
    77 
    78 int
    79 lockFile(int fd, dev_t dev, ino_t ino, int for_writing)
    80 {
    81     Lock key, *lock;
    82 
    83     ACQUIRE_LOCK(&file_lock_mutex);
    84 
    85     key.device = dev;
    86     key.inode  = ino;
    87 
    88     lock = lookupHashTable(obj_hash, (StgWord)&key);
    89 
    90     if (lock == NULL)
    91     {
    92         lock = stgMallocBytes(sizeof(Lock), "lockFile");
    93         lock->device = dev;
    94         lock->inode  = ino;
    95         lock->readers = for_writing ? -1 : 1;
    96         insertHashTable(obj_hash, (StgWord)lock, (void *)lock);
    97         insertHashTable(fd_hash, fd, lock);
    98         RELEASE_LOCK(&file_lock_mutex);
    99         return 0;
    100     }
    101     else
    102     {
    103         // single-writer/multi-reader locking:
    104         if (for_writing || lock->readers < 0) {
    105             RELEASE_LOCK(&file_lock_mutex);
    106             return -1;
    107         }
    108         insertHashTable(fd_hash, fd, lock);
    109         lock->readers++;
    110         RELEASE_LOCK(&file_lock_mutex);
    111         return 0;
    112     }
    113 }
    114 
    115 int
    116 unlockFile(int fd)
    117 {
    118     Lock *lock;
    119 
    120     ACQUIRE_LOCK(&file_lock_mutex);
    121 
    122     lock = lookupHashTable(fd_hash, fd);
    123     if (lock == NULL) {
    124         // errorBelch("unlockFile: fd %d not found", fd);
    125         // This is normal: we didn't know when calling unlockFile
    126         // whether this FD referred to a locked file or not.
    127         RELEASE_LOCK(&file_lock_mutex);
    128         return 1;
    129     }
    130 
    131     if (lock->readers < 0) {
    132         lock->readers++;
    133     } else {
    134         lock->readers--;
    135     }
    136 
    137     if (lock->readers == 0) {
    138         removeHashTable(obj_hash, (StgWord)lock, NULL);
    139         stgFree(lock);
    140     }
    141     removeHashTable(fd_hash, fd, NULL);
    142 
    143     RELEASE_LOCK(&file_lock_mutex);
    144     return 0;
    145 }
  • deleted file rts/posix/FileLock.h

    diff --git a/rts/posix/FileLock.h b/rts/posix/FileLock.h
    deleted file mode 100644
    index 72ab170..0000000
    + -  
    1 /* -----------------------------------------------------------------------------
    2  *
    3  * (c) The GHC Team, 2007
    4  *
    5  * File locking support as required by Haskell
    6  *
    7  * ---------------------------------------------------------------------------*/
    8 
    9 #ifndef POSIX_FILELOCK_H
    10 #define POSIX_FILELOCK_H
    11 
    12 RTS_PRIVATE void initFileLocking(void);
    13 RTS_PRIVATE void freeFileLocking(void);
    14 
    15 #endif /* POSIX_FILELOCK_H */