Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Infinite loop under some circumstances #9

Open
tipichris opened this issue Aug 16, 2016 · 0 comments
Open

Infinite loop under some circumstances #9

tipichris opened this issue Aug 16, 2016 · 0 comments

Comments

@tipichris
Copy link

Under certain circumstances the plugin can get into an (almost) infinite loop during database updates of logs.

The problem lies in this code, which looks as if it was written to avoid the issue, but a line has been missed:

        $key = APC_CACHE_LOG_INDEX;
        $index = apc_fetch($key);
        $fetched = -1;
        $loop = true;
        $values = array();
        // Retrieve all items and reset the counter
        while($loop) {
            for($i = $fetched+1; $i <= $index; $i++) {
                $values[] = apc_fetch(apc_cache_get_logindex($i));
            }

            $fetched = $index;

            if(apc_cas($key, $index, 0)) {
                $loop = false;
            } else {
                usleep(500);
            }
        }

with a lot of updates to do and more coming in fast, it can happen that by the time the for loop has run the value stored at APC_CACHE_LOG_INDEX has increased. In this case apc_cas will fail and $loop remains true. Once this happens, only another process successfully resetting the value stored at APC_CACHE_LOG_INDEX and then incrementing it back until it is equal to $index will break the loop.

What's missing is a reassignment of $index immediately after the usleep, ie

        $key = APC_CACHE_LOG_INDEX;
        $index = apc_fetch($key);
        $fetched = -1;
        $loop = true;
        $values = array();
        // Retrieve all items and reset the counter
        while($loop) {
            for($i = $fetched+1; $i <= $index; $i++) {
                $values[] = apc_fetch(apc_cache_get_logindex($i));
            }

            $fetched = $index;

            if(apc_cas($key, $index, 0)) {
                $loop = false;
            } else {
                usleep(500);
                $index = apc_fetch($key);
            }
        }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant