Skip to content
This repository has been archived by the owner on Dec 16, 2019. It is now read-only.

fix #580 #681 #688

Merged
merged 1 commit into from
May 29, 2017
Merged

fix #580 #681 #688

merged 1 commit into from
May 29, 2017

Conversation

sirsnyder
Copy link
Collaborator

@sirsnyder sirsnyder commented Mar 8, 2017

Cleanup on synchronized or reading a property is inconsistent, therefore cleanup should also happen on writing a property. Moreover the cleanup behavior on synchronized is misleading.

class myRec extends Threaded {
	public $data1;
	public $data2;
}

class storage extends Threaded {

	private $store = array();

	public function addRecord($key,$data) {
        	$this->store->synchronized(function () use ($key, $data)
        	{
			$this->store[$key] = $data;
		});
	}

	public function delAll() {
        	$this->store->synchronized(function ()
		{
			foreach($this->store as $key => $data)
			{
				unset($this->store[$key]);
			}
        	});
	}

	public function countRecs() {
		return count($this->store);
	}
}

class myThread extends Thread
{

	private static $type;

	public function __construct($type,$storage)
	{
		self::$type = $type;
		$this->storage = $storage;
	}

	public function run()
	{

		if (self::$type === 1) {
			while (true) {

				//if($this->storage->countRecs() == 0)
				{
					@$loop++;
					for($i = 0; $i < 30000; $i++)
					{
						$r = new  myRec();
						$r->data1 = 'data' . $i;
						$this->storage->addRecord($loop . '|' . $i, $r);
					}
				}

				sleep(5);

			}
		}

		if (self::$type === 2) {
			while (true) {
				//if($this->storage->countRecs() >= 30000)
				{
					$this->storage->delAll();
				}

				sleep(1);
				print "RECS:".$this->storage->countRecs()."\n";
			}

		}
	}
}

ini_set('memory_limit', '-1');

$storage = new storage();

$threads[0] = new myThread(1,$storage);
$threads[0]->start();

$threads[1] = new myThread(2,$storage);
$threads[1]->start();
$threads[1]->join();

This is a fix for #681 as well.

@sirsnyder sirsnyder changed the title fix #580 fix #580 #681 Mar 8, 2017
src/store.c Outdated
@@ -351,14 +352,18 @@ int pthreads_store_write(zval *object, zval *key, zval *write) {
normal refcounting, we'll just never read the reference
*/
rebuild_object_properties(&threaded->std);

pthreads_store_sync(object);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not immediately clear to me why this is needed - is it related to the memory leaks you're fixing? And do you have a test case for this?

Copy link
Collaborator Author

@sirsnyder sirsnyder Mar 8, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A test case might be difficult. I ran the script above for a certain time and watched the memory consumption. Any idea to trace this in a test script?

I've added pthreads_store_sync at this point to guarantee consistency with the behavior of reading properties. It is not necessary for the memory leak fix itself, just for the cleanup problems in #580.

Copy link
Collaborator

@tpunt tpunt Mar 9, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Testing the memory leak isn't really necessary, since it's quite unlikely a regression will be introduced here. I just wasn't sure how syncing the pthreads store linked to the memory leaks (it doesn't, but I see that you're using this PR to fix two different bugs).

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This has the potential to make unsynchronized writes extremely slow ... I don't like it ... would be good to find another way to do whatever you are trying to do ...

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Producer/Consumer: Producer Thread A writes properties and never reads them. Consumer Thread B reads/removes properties. Table std.properties in Thread A fills up, endlessly. I could limit pthreads_store_sync to Volatile objects, that might be a solution you like?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have again tested the script, without the pthreads_store_sync call. I must admit the memory isn't growing. My fault, I must have done something wrong.

@sirsnyder sirsnyder force-pushed the bug/580_memory_leak branch from 027a554 to 8fa211b Compare May 29, 2017 11:08
@tpunt
Copy link
Collaborator

tpunt commented May 29, 2017

@sirsnyder I'm also having trouble replicating the issue you're receiving without the syncing of the pthreads store. Do you have a smaller reproducing script that explicitly shows a difference with and without the syncing of stores on property writes?

The memory leak fixes look fine to me though.

@sirsnyder
Copy link
Collaborator Author

@tpunt that must have been an erroneous observation in htop. My fault. I've removed the pthreads_store_sync call.

@tpunt tpunt merged commit 8fa211b into krakjoe:master May 29, 2017
@tpunt
Copy link
Collaborator

tpunt commented May 29, 2017

Merged in 1dfeea7. Thanks!

@tpunt tpunt mentioned this pull request Jun 1, 2017
@tpunt tpunt removed the feedback label Jun 23, 2017
@sirsnyder sirsnyder deleted the bug/580_memory_leak branch August 23, 2017 12:00
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants