[SCM] WebKit Debian packaging branch, debian/experimental, updated. upstream/1.3.3-9427-gc2be6fc

ossy at webkit.org ossy at webkit.org
Wed Dec 22 15:58:31 UTC 2010


The following commit has been merged in the debian/experimental branch:
commit ce3268157216bff27d0911dd814b1d5ca5fb04ac
Author: ossy at webkit.org <ossy at webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Wed Nov 17 12:54:14 2010 +0000

    [NRWT] Make http locking similar to perl implementation
    https://bugs.webkit.org/show_bug.cgi?id=49187
    
    Patch by Gabor Rapcsanyi <rgabor at inf.u-szeged.hu> on 2010-11-17
    Reviewed by Tony Chang.
    
    * Scripts/webkitpy/common/system/file_lock.py: Added.
    * Scripts/webkitpy/common/system/file_lock_unittest.py: Added.
    * Scripts/webkitpy/layout_tests/port/http_lock.py:
    
    
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@72194 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/WebKitTools/ChangeLog b/WebKitTools/ChangeLog
index c2d8571..810712b 100644
--- a/WebKitTools/ChangeLog
+++ b/WebKitTools/ChangeLog
@@ -1,3 +1,14 @@
+2010-11-17  Gabor Rapcsanyi  <rgabor at inf.u-szeged.hu>
+
+        Reviewed by Tony Chang.
+
+        [NRWT] Make http locking similar to perl implementation
+        https://bugs.webkit.org/show_bug.cgi?id=49187
+
+        * Scripts/webkitpy/common/system/file_lock.py: Added.
+        * Scripts/webkitpy/common/system/file_lock_unittest.py: Added.
+        * Scripts/webkitpy/layout_tests/port/http_lock.py:
+
 2010-11-17  MORITA Hajime  <morrita at google.com>
 
         Reviewed by Kent Tamura.
diff --git a/WebKitTools/Scripts/webkitpy/common/system/file_lock.py b/WebKitTools/Scripts/webkitpy/common/system/file_lock.py
new file mode 100644
index 0000000..7296958
--- /dev/null
+++ b/WebKitTools/Scripts/webkitpy/common/system/file_lock.py
@@ -0,0 +1,83 @@
+#!/usr/bin/env python
+# Copyright (C) 2010 Gabor Rapcsanyi (rgabor at inf.u-szeged.hu), University of Szeged
+#
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY UNIVERSITY OF SZEGED ``AS IS'' AND ANY
+# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL UNIVERSITY OF SZEGED OR
+# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+# OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+"""This class helps to lock files exclusively across processes."""
+
+import logging
+import os
+import sys
+import time
+
+
+_log = logging.getLogger("webkitpy.common.system.file_lock")
+
+
+class FileLock(object):
+
+    def __init__(self, lock_file_path, max_wait_time_sec=20):
+        self._lock_file_path = lock_file_path
+        self._lock_file_descriptor = None
+        self._max_wait_time_sec = max_wait_time_sec
+
+    def _create_lock(self):
+        if sys.platform in ('darwin', 'linux2', 'cygwin'):
+            import fcntl
+            fcntl.flock(self._lock_file_descriptor, fcntl.LOCK_EX | fcntl.LOCK_NB)
+        elif sys.platform == 'win32':
+            import msvcrt
+            msvcrt.locking(self._lock_file_descriptor, msvcrt.LK_NBLCK, 32)
+
+    def _remove_lock(self):
+        if sys.platform in ('darwin', 'linux2', 'cygwin'):
+            import fcntl
+            fcntl.flock(self._lock_file_descriptor, fcntl.LOCK_UN)
+        elif sys.platform == 'win32':
+            import msvcrt
+            msvcrt.locking(self._lock_file_descriptor, msvcrt.LK_UNLCK, 32)
+
+    def acquire_lock(self):
+        self._lock_file_descriptor = os.open(self._lock_file_path, os.O_TRUNC | os.O_CREAT)
+        start_time = time.time()
+        while True:
+            try:
+                self._create_lock()
+                return True
+            except IOError:
+                if time.time() - start_time > self._max_wait_time_sec:
+                    _log.debug("File locking failed: %s" % str(sys.exc_info()))
+                    os.close(self._lock_file_descriptor)
+                    self._lock_file_descriptor = None
+                    return False
+
+    def release_lock(self):
+        try:
+            if self._lock_file_descriptor:
+                self._remove_lock()
+                os.close(self._lock_file_descriptor)
+                self._lock_file_descriptor = None
+            os.unlink(self._lock_file_path)
+        except (IOError, OSError):
+            _log.debug("Warning in release lock: %s" % str(sys.exc_info()))
diff --git a/WebKitTools/Scripts/webkitpy/common/system/file_lock_unittest.py b/WebKitTools/Scripts/webkitpy/common/system/file_lock_unittest.py
new file mode 100644
index 0000000..c5c1db3
--- /dev/null
+++ b/WebKitTools/Scripts/webkitpy/common/system/file_lock_unittest.py
@@ -0,0 +1,61 @@
+#!/usr/bin/env python
+# Copyright (C) 2010 Gabor Rapcsanyi (rgabor at inf.u-szeged.hu), University of Szeged
+#
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY UNIVERSITY OF SZEGED ``AS IS'' AND ANY
+# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL UNIVERSITY OF SZEGED OR
+# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+# OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+import os
+import tempfile
+import unittest
+
+from webkitpy.common.system.file_lock import FileLock
+
+
+class FileLockTest(unittest.TestCase):
+
+    def setUp(self):
+        self._lock_name = "TestWebKit" + str(os.getpid()) + ".lock"
+        self._lock_path = os.path.join(tempfile.gettempdir(), self._lock_name)
+        self._file_lock1 = FileLock(self._lock_path, 1)
+        self._file_lock2 = FileLock(self._lock_path, 1)
+
+    def tearDown(self):
+        self._file_lock1.release_lock()
+        self._file_lock2.release_lock()
+
+    def test_lock_lifecycle(self):
+        # Create the lock.
+        self._file_lock1.acquire_lock()
+        self.assertTrue(os.path.exists(self._lock_path))
+
+        # Try to lock again.
+        self.assertFalse(self._file_lock2.acquire_lock())
+
+        # Release the lock.
+        self._file_lock1.release_lock()
+        self.assertFalse(os.path.exists(self._lock_path))
+
+    def test_stuck_lock(self):
+        open(self._lock_path, 'w').close()
+        self._file_lock1.acquire_lock()
+        self._file_lock1.release_lock()
diff --git a/WebKitTools/Scripts/webkitpy/layout_tests/port/http_lock.py b/WebKitTools/Scripts/webkitpy/layout_tests/port/http_lock.py
index d65801d..8995b21 100644
--- a/WebKitTools/Scripts/webkitpy/layout_tests/port/http_lock.py
+++ b/WebKitTools/Scripts/webkitpy/layout_tests/port/http_lock.py
@@ -36,6 +36,7 @@ import tempfile
 import time
 
 from webkitpy.common.system.executive import Executive
+from webkitpy.common.system.file_lock import FileLock
 
 
 _log = logging.getLogger("webkitpy.layout_tests.port.http_lock")
@@ -52,10 +53,9 @@ class HttpLock(object):
         self._lock_file_path_prefix = os.path.join(self._lock_path,
                                                    self._lock_file_prefix)
         self._guard_lock_file = os.path.join(self._lock_path, guard_lock)
+        self._guard_lock = FileLock(self._guard_lock_file)
         self._process_lock_file_name = ""
         self._executive = Executive()
-        # maximum wait time for the lock creation
-        self._guard_lock_max_wait = 1 * 60
 
     def cleanup_http_lock(self):
         """Delete the lock file if exists."""
@@ -95,35 +95,31 @@ class HttpLock(object):
                 _log.debug("Removing stuck lock file: %s" % lock_list[0])
                 os.unlink(lock_list[0])
                 return
-        except IOError, OSError:
+        except (IOError, OSError):
             return
         return int(current_pid)
 
     def _create_lock_file(self):
         """The lock files are used to schedule the running test sessions in first
-        come first served order. The sequential guard lock ensures that the lock
-        numbers are sequential."""
+        come first served order. The guard lock ensures that the lock numbers are
+        sequential."""
         if not os.path.exists(self._lock_path):
             _log.debug("Lock directory does not exist: %s" % self._lock_path)
             return False
 
-        start_time = time.time()
-        while(True):
-            try:
-                sequential_guard_lock = os.open(self._guard_lock_file, os.O_CREAT | os.O_EXCL)
-                self._process_lock_file_name = (self._lock_file_path_prefix +
-                                                str(self._next_lock_number()))
-                lock_file = open(self._process_lock_file_name, 'w')
-                _log.debug("Creating lock file: %s" % self._process_lock_file_name)
-                lock_file.write(str(os.getpid()))
-                lock_file.close()
-                os.close(sequential_guard_lock)
-                os.unlink(self._guard_lock_file)
-                return True
-            except OSError:
-                if time.time() - start_time > self._guard_lock_max_wait:
-                    _log.debug("Lock does not created: %s" % str(sys.exc_info()))
-                    return False
+        if not self._guard_lock.acquire_lock():
+            _log.debug("Guard lock timed out!")
+            return False
+
+        self._process_lock_file_name = (self._lock_file_path_prefix +
+                                        str(self._next_lock_number()))
+        _log.debug("Creating lock file: %s" % self._process_lock_file_name)
+        lock_file = open(self._process_lock_file_name, 'w')
+        lock_file.write(str(os.getpid()))
+        lock_file.close()
+        self._guard_lock.release_lock()
+        return True
+
 
     def wait_for_httpd_lock(self):
         """Create a lock file and wait until it's turn comes. If something goes wrong

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list