Permalink
Browse files

reverted to 25cf50d because later revision introduced rare cpu hoggin…

…g bug
  • Loading branch information...
1 parent 06081d4 commit 09ded0cb1bb9cb204c719dc9972b04067fa09903 Yiding Jia committed with adonohue Jul 13, 2010
Showing with 15 additions and 104 deletions.
  1. +7 −17 src/__init__.py
  2. +8 −20 src/phpsh.php
  3. +0 −67 src/tests.py
View
@@ -726,10 +726,9 @@ def wait_for_comm_finish(self, defer_output=False):
if ret_code != None:
if debug:
print "NOOOOO"
- print "subprocess died with return code: " + repr(ret_code)
died = True
break
- while True:
+ while not died:
# line-buffer stdout and stderr
if debug:
print "start loop"
@@ -748,7 +747,8 @@ def wait_for_comm_finish(self, defer_output=False):
out_buff_i = 1
buff = os.read(r.fileno(), buffer_size)
if not buff:
- # process has died, will be dealt with in outer loop
+ # process has died
+ died = True
break
out_buff[out_buff_i] += buff
last_nl_pos = out_buff[out_buff_i].rfind("\n")
@@ -763,14 +763,9 @@ def wait_for_comm_finish(self, defer_output=False):
err.write(l)
out_buff[out_buff_i] = \
out_buff[out_buff_i][last_nl_pos + 1:]
- # at this point either:
- # the php instance died
- # select timed out
- l = self.comm_file.readline()
- if l.startswith("child"):
- os.kill(self.p.pid, signal.SIGHUP)
- self.p.pid = int(l.split()[1])
- elif l.startswith("ready"):
+ # don't sleep if the command is already done
+ # (even tho sleep period is small; maximize responsiveness)
+ if self.comm_file.readline():
break
time.sleep(comm_poll_timeout)
@@ -1006,8 +1001,6 @@ def end_process(self, alarm=False):
# shutdown php, if it doesn't exit in 5s, kill -9
if alarm:
signal.signal(signal.SIGALRM, sigalrm_handler)
- # if we have fatal-restart prevention, the child proess can't be waited
- # on since it's no longer a child of this process
try:
self.p.stdout.close()
self.p.stderr.close()
@@ -1018,9 +1011,6 @@ def end_process(self, alarm=False):
except (IOError, OSError, KeyboardInterrupt):
os.kill(self.p.pid, signal.SIGKILL)
# collect the zombie
- try:
- os.waitpid(self.p.pid, 0)
- except (OSError):
- pass
+ os.waitpid(self.p.pid, 0)
self.p = None
View
@@ -529,26 +529,14 @@ function interactive_loop() {
if ($this->do_color) {
echo "\033[33m"; // yellow
}
-
- $parent_pid = posix_getpid();
- $pid = pcntl_fork();
- $evalue = null;
- if ($pid) {
- pcntl_wait($status);
- } else {
- try {
- $evalue = eval($buffer);
- } catch (Exception $e) {
- // unfortunately, almost all exceptions that aren't explicitly thrown
- // by users are uncatchable :(
- fwrite(STDERR, 'Uncaught exception: '.get_class($e).': '.
- $e->getMessage()."\n");
- $evalue = null;
- }
-
- // if we are still alive..
- $childpid = posix_getpid();
- fwrite($this->_comm_handle, "child $childpid\n");
+ try {
+ $evalue = eval($buffer);
+ } catch (Exception $e) {
+ // unfortunately, almost all exceptions that aren't explicitly thrown
+ // by users are uncatchable :(
+ fwrite(STDERR, 'Uncaught exception: '.get_class($e).': '.
+ $e->getMessage()."\n");
+ $evalue = null;
}
if ($buffer != "xdebug_break();\n") {
View
@@ -1,67 +0,0 @@
-import unittest
-from phpsh import PhpshState, line_encode, do_sugar
-
-
-class TestPhpsh(unittest.TestCase):
-
- def setUp(self):
- self.ps = PhpshState(
- cmd_incs=set(),
- do_color=False,
- do_echo=False,
- codebase_mode='none',
- do_autocomplete=False,
- do_ctags=False,
- interactive=True,
- with_xdebug=False,
- verbose=False)
-
- def php(self, line):
- expr = line_encode(do_sugar(line)) + '\n'
- return self.ps.do_expr(expr).strip()
-
- def assertPhp(self, line, expected=''):
- self.assertEqual(str(expected), self.php(line))
-
- def test_simple(self):
- self.assertPhp('=1+1', 2)
- self.assertPhp('$a=3')
- self.assertPhp('=$a+2', 5)
-
- def test_long_running_func(self):
- func = ("function foo(){ "
- " $a=0;"
- " for ($i=0; $i<100000; $i++)"
- " $a+=1;"
- " return $a;"
- "}")
- self.php(func)
- self.assertPhp('=foo()', '100000')
-
- def test_undefined_func_check(self):
- # make sure state is maintained after undefined function call
- # is avoided.
- self.assertPhp('$a=3')
- self.assertPhp(
- 'does_not_exist()',
- 'Not executing input: Possible call to undefined '
- 'function does_not_exist()\n'
- 'See /etc/phpsh/config.sample to disable UndefinedFunctionCheck.')
- self.assertPhp('=$a', 3)
-
- def test_fatal(self):
- # create some state
- self.assertPhp('$a=3')
-
- # run a function that does not exist (and get around the simple check)
- self.assertPhp("$func = 'does_not_exist'")
- result = self.php('$func()')
- expected = 'Fatal error: Call to undefined function does_not_exist()'
- self.assertTrue(expected in result)
-
- # verify that the state is still there.
- self.assertPhp('=$a', 3)
-
-
-if __name__ == '__main__':
- unittest.main()

0 comments on commit 09ded0c

Please sign in to comment.