Changeset 3048

Show
Ignore:
Timestamp:
11/06/06 23:18:06 (17 years ago)
Author:
jerome
Message:

Locking code should now work as expected, even when CUPS is stopped and
the cupspykota backend killed uncleanly.

Location:
pykota/trunk
Files:
3 modified

Legend:

Unmodified
Added
Removed
  • pykota/trunk/bin/cupspykota

    r3041 r3048  
    130130    def waitForLock(self) :     
    131131        """Waits until we can acquire the lock file.""" 
    132         self.logdebug("Waiting for lock...") 
     132        self.logdebug("Waiting for lock %s to become available..." % self.lockfilename) 
    133133        haslock = False 
    134         try : 
    135             while not haslock : 
    136                 self.logdebug("Trying to acquire lock %s" % self.lockfilename) 
    137                 try : 
    138                     self.lockfile = os.open(self.lockfilename,  
    139                                             os.O_CREAT | os.O_EXCL | os.O_WRONLY,  
    140                                             0600) 
    141                 except OSError, error :                      
    142                     # IMPORTANT : we don't check anymore if the other process 
    143                     # is still alive, otherwise we could inadvertantly delete 
    144                     # a lock file created by a different print server in the 
    145                     # same directory (load balancing). 
    146                     # I think the lock is removed in all cases anyway, excepted 
    147                     # when the admin kills -9 cupspykota. 
    148                     if error.errno == errno.EEXIST : 
    149                         self.logdebug("Lock not available. Waiting a bit...") 
    150                     else :     
    151                         self.logdebug("Lock not available : %s. Waiting a bit..." % error) 
    152                     time.sleep(0.25) # No hurry :) 
    153                 else :     
    154                     os.write(self.lockfile, str(self.pid)) 
    155                     haslock = True     
    156         except IOError :             
    157             self.logdebug("I/O Error while waiting for lock.") 
    158         else : 
    159             self.logdebug("Lock acquired.") 
     134        while not haslock : 
     135            try : 
     136                # open the lock file, optionally creating it if needed. 
     137                self.lockfile = open(self.lockfilename, "a+") 
     138                 
     139                # we wait indefinitely for the lock to become available. 
     140                # works over NFS too. 
     141                fcntl.lockf(self.lockfile, fcntl.LOCK_EX) 
     142                haslock = True 
     143                 
     144                self.logdebug("Lock %s acquired." % self.lockfilename) 
     145                 
     146                # Here we save the PID in the lock file, but we don't use 
     147                # it, because the lock file may be in a directory shared 
     148                # over NFS between two (or more) print servers, so the PID 
     149                # has no meaning in this case. 
     150                self.lockfile.truncate(0) 
     151                self.lockfile.seek(0, 0) 
     152                self.lockfile.write(str(self.pid)) 
     153                self.lockfile.flush() 
     154            except IOError :             
     155                self.logdebug("I/O Error while waiting for lock %s" % self.lockfilename) 
     156                time.sleep(0.25) 
    160157                     
    161158    def discoverOtherBackends(self) :     
     
    535532        PyKotaTool.clean(self)     
    536533        if (self.lockfile is not None) and os.path.exists(self.lockfilename) : 
    537             self.logdebug("Removing lock...") 
     534            self.logdebug("Unlocking %s..." %  self.lockfilename) 
    538535            try : 
    539                 os.close(self.lockfile) 
    540                 os.unlink(self.lockfilename) 
     536                fcntl.lockf(self.lockfile, fcntl.LOCK_UN) 
     537                self.lockfile.close() 
    541538            except :     
    542                 self.printInfo("Problem while removing lock file %s" % self.lockfilename, "error") 
     539                self.printInfo("Problem while unlocking %s" % self.lockfilename, "error") 
    543540            else :     
    544                 self.logdebug("Lock file %s removed." % self.lockfilename) 
     541                self.logdebug("%s unlocked." % self.lockfilename) 
    545542        self.logdebug("Clean.") 
    546543             
  • pykota/trunk/NEWS

    r3040 r3048  
    2222PyKota NEWS : 
    2323        
     24    - 1.25alpha15 (2006-11-06) :    
     25     
     26        - Finally simplified the locking code again, and checked that no 
     27          stalled lock can persist. The lock files remain on disk though, 
     28          but it is a small price to pay. 
     29           
    2430    - 1.25alpha14 (2006-10-13) : 
    2531       
  • pykota/trunk/pykota/version.py

    r3036 r3048  
    2222# 
    2323 
    24 __version__ = "1.25alpha14_unofficial" 
     24__version__ = "1.25alpha15_unofficial" 
    2525 
    2626__doc__ = "PyKota : a complete Printing Quota Solution for CUPS."