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 */