diff --git a/dmemcache.inc b/dmemcache.inc
index 31759bf..3366d8b 100644
--- a/dmemcache.inc
+++ b/dmemcache.inc
@@ -101,24 +101,7 @@ function dmemcache_get($key, $bin = 'cache') {
   $success = '0';
   if ($mc = dmemcache_object($bin)) {
     $result = $mc->get($full_key);
-    if ($result) {
-      // We check $result->expire to see if the object has expired.  If so, we
-      // try and grab a lock.  If we get the lock, we return FALSE instead of
-      // the cached object which should cause it to be rebuilt.  If we do not
-      // get the lock, we return the cached object.  The goal here is to avoid
-      // cache stampedes. 
-      // By default the cache stampede semaphore is held for 15 seconds.  This
-      // can be adjusted by setting the memcache_stampede_semaphore variable.
-      // TODO: Can we log when a sempahore expires versus being intentionally
-      // freed to track when this is happening?
-      if (isset($result->expire) && $result->expire !== CACHE_PERMANENT && $result->expire <= $_SERVER['REQUEST_TIME'] && dmemcache_add($full_key .'_semaphore', '', variable_get('memcache_stampede_semaphore', 15))) {
-        $result = FALSE;
-      }
-      else {
-        $success = '1';
-      }
-    }
-    $statistics[] = $success;
+    $statistics[] = (bool) $result;
     $_memcache_statistics[] = $statistics;
 
     return $result;
diff --git a/memcache.inc b/memcache.inc
index 2021b4c..b76790e 100644
--- a/memcache.inc
+++ b/memcache.inc
@@ -34,8 +34,17 @@ function cache_get($cid, $table = 'cache') {
   // Retrieve the item from the cache.
   $cache = dmemcache_get($cid, $table);
 
-  if (!is_object($cache)) {
-    return FALSE;
+  if (!$cache) {
+    if (variable_get('memcache_stampede_protection', FALSE) && !lock_acquire("$cid:$bin", variable_get('memcache_stampede_semaphore', 15))) {
+      lock_wait("$cid:$bin", variable_get('memcache_stampede_max_wait', (int) variable_get('memcache_stampede_semaphore', 15) / 3));
+      $cache = dmemcache_get($cid, $table);
+      if (!$cache) {
+        return FALSE;
+      }
+    }
+    else {
+      return FALSE;
+    }
   }
 
   $wildcard_flushes = variable_get('memcache_wildcard_flushes', array());
@@ -85,6 +94,26 @@ function cache_get($cid, $table = 'cache') {
     // Cache item expired, return FALSE.
     return FALSE;
   }
+  // We check $result->expire to see if the object has expired.  If so, we
+  // try and grab a lock.  If we get the lock, we return FALSE instead of
+  // the cached object which should cause it to be rebuilt.  If we do not
+  // get the lock, we return the cached object.  The goal here is to avoid
+  // cache stampedes. 
+  // By default the cache stampede semaphore is held for 15 seconds.  This
+  // can be adjusted by setting the memcache_stampede_semaphore variable.
+  // TODO: Can we log when a sempaphore expires versus being intentionally
+  // freed to track when this is happening?
+  if (isset($cache->expire) && $cache->expire !== CACHE_PERMANENT && $cache->expire <= $_SERVER['REQUEST_TIME']) {
+    if (variable_get('memcache_stampede_protection', FALSE)) {
+      if (lock_acquire("$cid:$bin", variable_get('memcache_stampede_semaphore', 15))) {
+        return FALSE;
+      }
+    }
+    else {
+      return FALSE;
+    }
+  }
+
   return $cache;
 }
 
@@ -148,6 +177,9 @@ function cache_set($cid, $data, $table = 'cache', $expire = CACHE_PERMANENT, $he
   // Other requests for the expired object while it is still being rebuilt get
   // the expired object.
   dmemcache_set($cid, $cache, 0, $table);
+  if (isset($GLOBALS['locks']["$cid:$table"])) {
+    lock_release("$cid:$table");
+  }
 }
 
 /**
