1<?php
2/* Copyright (c) 1998-2013 ILIAS open source, Extended GPL, see docs/LICENSE */
3
4require_once 'Modules/TestQuestionPool/classes/class.ilAssQuestionProcessLocker.php';
5
6/**
7 * @author		Björn Heyser <bheyser@databay.de>
8 * @version		$Id$
9 *
10 * @package     Modules/Test
11 */
12class ilTestProcessLockerFile extends ilTestProcessLocker
13{
14    const PROCESS_NAME_TEST_START_LOCK_CHECK = 'testStartLockCheck';
15    const PROCESS_NAME_RANDOM_PASS_BUILD = 'randomPassBuild';
16    const PROCESS_NAME_TEST_FINISH = 'testFinish';
17
18    /**
19     * @var ilTestProcessLockFileStorage
20     */
21    protected $lockFileStorage;
22
23    /**
24     * @var resource
25     */
26    protected $lockFileHandles;
27
28    /**
29     * ilTestProcessLockerFile constructor.
30     * @param ilTestProcessLockFileStorage $lockFileStorage
31     */
32    public function __construct(ilTestProcessLockFileStorage $lockFileStorage)
33    {
34        $this->lockFileStorage = $lockFileStorage;
35        $this->lockFileHandles = array();
36    }
37
38    /**
39     * {@inheritdoc}
40     */
41    protected function onBeforeExecutingTestStartOperation()
42    {
43        parent::onBeforeExecutingTestStartOperation();
44        $this->requestLock(self::PROCESS_NAME_TEST_START_LOCK_CHECK);
45    }
46
47    /**
48     * {@inheritdoc}
49     */
50    protected function onAfterExecutingTestStartOperation()
51    {
52        $this->releaseLock(self::PROCESS_NAME_TEST_START_LOCK_CHECK);
53        parent::onAfterExecutingTestStartOperation();
54    }
55
56    /**
57     * {@inheritdoc}
58     */
59    protected function onBeforeExecutingRandomPassBuildOperation($withTaxonomyTables = false)
60    {
61        parent::onBeforeExecutingRandomPassBuildOperation($withTaxonomyTables);
62        $this->requestLock(self::PROCESS_NAME_RANDOM_PASS_BUILD);
63    }
64
65    /**
66     * {@inheritdoc}
67     */
68    protected function onAfterExecutingRandomPassBuildOperation($withTaxonomyTables = false)
69    {
70        $this->releaseLock(self::PROCESS_NAME_RANDOM_PASS_BUILD);
71        parent::onAfterExecutingRandomPassBuildOperation($withTaxonomyTables);
72    }
73
74    /**
75     * {@inheritdoc}
76     */
77    protected function onBeforeExecutingTestFinishOperation()
78    {
79        parent::onBeforeExecutingTestStartOperation();
80        $this->requestLock(self::PROCESS_NAME_TEST_FINISH);
81    }
82
83    /**
84     * {@inheritdoc}
85     */
86    protected function onAfterExecutingTestFinishOperation()
87    {
88        $this->releaseLock(self::PROCESS_NAME_TEST_FINISH);
89        parent::onAfterExecutingTestStartOperation();
90    }
91
92    private function requestLock($processName)
93    {
94        $lockFilePath = $this->getLockFilePath($processName);
95        $this->lockFileHandles[$processName] = fopen($lockFilePath, 'w');
96        flock($this->lockFileHandles[$processName], LOCK_EX);
97    }
98
99    private function getLockFilePath($processName)
100    {
101        $path = $this->lockFileStorage->getPath();
102        return $path . '/' . $processName . '.lock';
103    }
104
105    private function releaseLock($processName)
106    {
107        flock($this->lockFileHandles[$processName], LOCK_UN);
108        fclose($this->lockFileHandles[$processName]);
109    }
110}
111