php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #58805 apc_add() Bug
Submitted: 2009-08-13 17:56 UTC Modified: 2009-10-12 14:48 UTC
From: info at mostinfo dot net Assigned:
Status: Closed Package: APC (PECL)
PHP Version: 5.2.11 OS: FreeBSD 7.2
Private report: No CVE-ID: None
 [2009-08-13 17:56 UTC] info at mostinfo dot net
Description:
------------
apc_add('foo', true, $ttl) always returns false on subsequent visits during the execution of the script, despite the fact that the $ttl has expired

Reproduce code:
---------------
<?php

while(!apc_add('test_add', true, 5)) {
    echo "wait..<br>\n";
    usleep(500);
}
echo "Have lock!";

?>

Expected result:
----------------
Launch 1:
Have lock!

Launch 2:
wait..
wait..
...
wait..
Have lock!

Actual result:
--------------
Launch 1:
Have lock!

Launch 2:
wait..
wait..
wait..
...
infinite loop

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2009-08-14 07:19 UTC] gopalv82 at yahoo dot com
Ah, this is a fall-out of the new cache-slam protection.

It sort of assumes what you're doing is going to slam the cache (you are, in some sense) and fails.
 [2009-08-14 09:19 UTC] info at mostinfo dot net
how to bypass it?
 [2009-08-21 08:04 UTC] info at mostinfo dot net
Is it impossible?
 [2009-08-21 09:45 UTC] gopalv82 at yahoo dot com
No, just give > 1 seconds between apc_add()

But I realize that it's impossible to do this on a multi-process box.

apc_add() is a bad way to go about doing this actually. Let me think about a better API call to do what you want to achieve (i.e "mark caller $x as the owner of something with a time out") instead of break my last fix.

Gimme a bit more time to brainstorm.
 [2009-08-26 14:52 UTC] info at mostinfo dot net
Thanks in advance, I'm really looking forward solutions!
 [2009-08-31 17:34 UTC] info at mostinfo dot net
Are you sure that the problem is due to the cache-slam protection? In version 3.0.19 a situation similar
 [2009-09-22 06:52 UTC] kalle@php.net
Can you try the latest SVN trunk of APC and see if this issue is resolved?
 [2009-09-22 15:50 UTC] info at mostinfo dot net
Issue remains :(
 [2009-09-25 03:13 UTC] info at mostinfo dot net
Sorry for my bad english. Issue is not resolved.
 [2009-10-01 12:29 UTC] askalski at gmail dot com
APC uses the timestamp at the start of the request for all subsequent cache operations in the script.  (The point of this is to cut down on "expensive" time() system calls.)  The drawback is unexpected behavior such as what you're seeing.

Example: The key 'foo' expires at 12:00:05.  You start your script at 12:00:01.  APC will use the timestamp 12:00:01 for the entire duration of the script, so no matter how long you sleep(), the key always expires "4 seconds from now".

The beta version of APC has a new configuration variable "apc.use_request_time" (default On), that you can use to disable this feature.
 [2009-10-01 17:51 UTC] shire@php.net
thanks askalski.  

info@: can you try upgrading and confirm if using this setting fixes your scenario?

Although I agree with Gopal, this probably isn't the best way to get exclusive access to resources.  Perhaps a wrapper around the new compare and swap would be better instead?  (ie: int apc_cas(string key, long old, long new))  Locking isn't easy so a more fail-proof use might be in order, what's the use case here btw?
 [2009-10-04 06:24 UTC] gopalv82 at yahoo dot com
I did think a lot about apc_cas, except for one critical part about a timeout expiring it out.

I'm actually thinking of a completely clean extension to handle mutexes and timeouts properly in php code?
 [2009-10-06 04:22 UTC] info at mostinfo dot net
With the new configuration variable "apc.use_request_time" = 0, this problem is solved!

Perhaps the best way to get exclusive access to resources would be to use a special command, such as apc_lock ( 'key_name') and apc_unlock ( 'key_name'), as is done in eAccelerator?
 [2009-10-12 14:48 UTC] shire@php.net
Marking this bug as closed, as the problem appears to be fixed with the user_request_time configuration option.  We'll have to think about the locking mechanisms and what can be done there, it seems this does come up regularly...
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sat Jun 01 07:01:30 2024 UTC