diff --git a/core/includes/lock.inc b/core/includes/lock.inc
index 7dd8db3..4504d81 100644
--- a/core/includes/lock.inc
+++ b/core/includes/lock.inc
@@ -255,6 +255,24 @@ function lock_release($name) {
 }
 
 /**
+ * Release a lock acquired in another request.
+ *
+ * This should only be used if the request that originally acquired the lock has
+ * died without releasing it, e.g. due to a server crash.
+ *
+ * @param $name
+ *   The name of the lock.
+ */
+function lock_force_release($name) {
+  global $locks;
+
+  unset($locks[$name]);
+  db_delete('semaphore')
+    ->condition('name', $name)
+    ->execute();
+}
+
+/**
  * Release all previously acquired locks.
  */
 function lock_release_all($lock_id = NULL) {
diff --git a/core/modules/simpletest/tests/lock.test b/core/modules/simpletest/tests/lock.test
index 0b423ff..2b1773d 100644
--- a/core/modules/simpletest/tests/lock.test
+++ b/core/modules/simpletest/tests/lock.test
@@ -46,6 +46,14 @@ class LockFunctionalTest extends DrupalWebTestCase {
     // We cannot renew it, since the other thread took it.
     $this->assertFalse(lock_acquire('system_test_lock_acquire'), t('Lock cannot be extended by this request.'), t('Lock'));
 
+    // Force-release our lock from the other request.
+    $lock_acquired = 'TRUE: Lock successfully acquired in system_test_lock_force_release()';
+    $lock_not_acquired_exit = 'FALSE: Lock not acquired in system_test_lock_force_release()';
+    $this->assertTrue(lock_acquire('system_test_lock_force_release'), t('Lock acquired by this request.'), t('Lock'));
+    $this->drupalGet('system-test/lock-force-release');
+    $this->assertText($lock_acquired, t('Lock acquired by the other request, force-breaking our lock.'), t('Lock'));
+    $this->assertFalse(lock_acquire('system_test_lock_force_release'), t('Lock cannot be extended by this request.'), t('Lock'));
+
     // Check the shut-down function.
     $lock_acquired_exit = 'TRUE: Lock successfully acquired in system_test_lock_exit()';
     $lock_not_acquired_exit = 'FALSE: Lock not acquired in system_test_lock_exit()';
diff --git a/core/modules/simpletest/tests/system_test.module b/core/modules/simpletest/tests/system_test.module
index e6d1f35..853fee9 100644
--- a/core/modules/simpletest/tests/system_test.module
+++ b/core/modules/simpletest/tests/system_test.module
@@ -71,6 +71,13 @@ function system_test_menu() {
     'type' => MENU_CALLBACK,
   );
 
+  $items['system-test/lock-force-release'] = array(
+    'title' => 'Lock acquire',
+    'page callback' => 'system_test_lock_force_release',
+    'access callback' => TRUE,
+    'type' => MENU_CALLBACK,
+  );
+
   $items['system-test/lock-exit'] = array(
     'title' => 'Lock acquire then exit',
     'page callback' => 'system_test_lock_exit',
@@ -291,6 +298,19 @@ function system_test_lock_acquire() {
 }
 
 /**
+ * Force-release a named lock and acquire it.
+ */
+function system_test_lock_force_release() {
+  lock_force_release('system_test_lock_force_release');
+  if (lock_acquire('system_test_lock_force_release')) {
+    return 'TRUE: Lock successfully acquired in system_test_lock_force_release()';
+  }
+  else {
+    return 'FALSE: Lock not acquired in system_test_lock_force_release()';
+  }
+}
+
+/**
  * Try to acquire a specific lock, and then exit.
  */
 function system_test_lock_exit() {
