Changeset 688

Show
Ignore:
Timestamp:
08/11/06 00:12:08 (16 years ago)
Author:
jerome
Message:

Now serializes accesses to the same device by different print queues
or print servers, just like PyKota.

Location:
tea4cups/trunk
Files:
2 modified

Legend:

Unmodified
Added
Removed
  • tea4cups/trunk/NEWS

    r684 r688  
    2323Tea4CUPS News : 
    2424 
    25   * 3.12 (2006-08-10) : 
     25  * 3.12 (2006-08-11) : 
    2626   
     27    - Serializes accesses to the same device from different queues  
     28      or print servers through file locking facilities (works over 
     29      NFS). 
     30     
    2731    - Improved support for CUPS 1.2.x and higher. 
    2832     
  • tea4cups/trunk/tea4cups

    r687 r688  
    8383import signal 
    8484import socket 
     85import fcntl 
    8586import urllib2 
    8687from struct import pack, unpack 
    8788 
    88 __version__ = "3.12alpha2_unofficial" 
     89__version__ = "3.12_unofficial" 
    8990 
    9091class TeeError(Exception): 
     
    909910        self.config = None 
    910911        self.conffile = None 
    911  
     912        self.LockFile = None 
     913 
     914    def waitForLock(self) :     
     915        """Waits until we can acquire the lock file.""" 
     916        self.logDebug("Waiting for lock...") 
     917        lockfilename = self.DeviceURI.replace("/", ".") 
     918        lockfilename = lockfilename.replace(":", ".") 
     919        lockfilename = lockfilename.replace("?", ".") 
     920        lockfilename = lockfilename.replace("&", ".") 
     921        lockfilename = lockfilename.replace("@", ".") 
     922        lockfilename = os.path.join(self.Directory, "%s-%s..LCK" % (self.myname, lockfilename)) 
     923        stillrunning = True 
     924        while 1 : 
     925            self.LockFile = open(lockfilename, "a+") 
     926            fcntl.lockf(self.LockFile, fcntl.LOCK_EX) # Will wait until lock available 
     927            self.LockFile.seek(0, 0)       
     928            try :  
     929                oldpid = int(self.LockFile.readlines()[-1].strip()) 
     930            except :     
     931                stillrunning = False 
     932            else :     
     933                try : 
     934                    os.kill(oldpid, 0) 
     935                except OSError :     
     936                    stillrunning = False 
     937            if not stillrunning :         
     938                self.LockFile.truncate(0) 
     939                self.LockFile.seek(0, 0) 
     940                self.LockFile.write("%s\n" % self.pid) 
     941                self.LockFile.flush() 
     942                break 
     943            else :     
     944                time.sleep(0.1) 
     945        self.logDebug("Lock acquired.") 
     946         
    912947    def readConfig(self) : 
    913948        """Reads the configuration file.""" 
     
    11181153            jbing = jbing[-1] 
    11191154        (dummy, self.JobBilling) = jbing 
    1120  
    1121  
     1155         
    11221156    def parseIPPRequestFile(self) : 
    11231157        """Parses the IPP message file and returns a tuple (filename, parsedvalue).""" 
     
    12271261    def cleanUp(self) : 
    12281262        """Cleans up the place.""" 
     1263        self.logDebug("Cleaning up...") 
    12291264        if (not isTrue(self.getPrintQueueOption(self.PrinterName, "keepfiles", ignore=1))) \ 
    12301265            and os.path.exists(self.DataFile) : 
     
    12331268            except OSError, msg :     
    12341269                self.logInfo("Problem when removing %s : %s" % (self.DataFile, msg), "error") 
     1270        self.logDebug("Removing lock...") 
     1271        try : 
     1272            fcntl.flock(self.LockFile, fcntl.LOCK_UN) 
     1273            self.LockFile.close() 
     1274            # NB : we don't remove the lock file, since it might already be opened by another process. 
     1275        except :     
     1276            self.logInfo("Problem while removing lock.", "error") 
     1277        else :     
     1278            self.logDebug("Lock removed.") 
     1279        self.logDebug("Clean.") 
    12351280 
    12361281    def runBranches(self) : 
     
    14301475                wrapper.readConfig() 
    14311476                wrapper.initBackend() 
     1477                wrapper.waitForLock() 
    14321478                wrapper.saveDatasAndCheckSum() 
    14331479                wrapper.exportAttributes()