# HG changeset patch
# User Jeroen Demeyer <jdemeyer@cage.ugent.be>
# Date 1362667188 -3600
# Node ID c0ae228090592c3d0346677a682e910e5c215873
# Parent e281b0f00aa75bb7618d7a3a503286d8af88e892
Race condition in gap_reset_workspace()
diff --git a/sage/interfaces/gap.py b/sage/interfaces/gap.py
a
|
b
|
|
708 | 708 | sage: rc = gap.interrupt(timeout=1) |
709 | 709 | sage: gap._eval_using_file_cutoff = cutoff |
710 | 710 | |
711 | | The following tests against a bug fixed at trac ticket #10296: |
| 711 | The following tests against a bug fixed at :trac:`10296`:: |
712 | 712 | |
713 | 713 | sage: gap(3) |
714 | 714 | 3 |
… |
… |
|
1173 | 1173 | Expect._start(self, "Failed to start GAP.") |
1174 | 1174 | except Exception: |
1175 | 1175 | if self.__use_workspace_cache and first_try: |
1176 | | print "A workspace appears to have been corrupted... automatically rebuilding (this is harmless)." |
1177 | 1176 | first_try = False |
1178 | 1177 | self.quit(timeout=0) |
1179 | 1178 | expect.failed_to_start.remove(self.name()) |
1180 | 1179 | gap_reset_workspace(verbose=False) |
1181 | 1180 | Expect._start(self, "Failed to start GAP.") |
1182 | 1181 | self._session_number = n |
1183 | | return |
1184 | | raise |
| 1182 | self.__make_workspace = False |
| 1183 | else: |
| 1184 | raise |
1185 | 1185 | |
1186 | 1186 | if self.__use_workspace_cache and self.__make_workspace: |
1187 | 1187 | self.save_workspace() |
… |
… |
|
1253 | 1253 | # SaveWorkspace can only be used at the main gap> prompt. It cannot |
1254 | 1254 | # be included in the body of a loop or function, or called from a |
1255 | 1255 | # break loop. |
1256 | | self.eval('SaveWorkspace("%s");'%WORKSPACE, allow_use_file=False) |
| 1256 | |
| 1257 | # Save the worksheet to a temporary file and then move that |
| 1258 | # file in place to avoid race conditions. |
| 1259 | WORKSPACE_TMP = "%s-%s"%(WORKSPACE, self.pid()) |
| 1260 | self.eval('SaveWorkspace("%s");'%WORKSPACE_TMP, allow_use_file=False) |
| 1261 | try: |
| 1262 | os.rename(WORKSPACE_TMP, WORKSPACE) |
| 1263 | except OSError: |
| 1264 | # Some operating systems might not support in-place |
| 1265 | # renaming. We delete the original file first. |
| 1266 | os.unlink(WORKSPACE) |
| 1267 | os.rename(WORKSPACE_TMP, WORKSPACE) |
1257 | 1268 | |
1258 | 1269 | # Todo -- this -- but there is a tricky "when does it end" issue! |
1259 | 1270 | # Maybe do via a file somehow? |
… |
… |
|
1434 | 1445 | default when Sage first starts GAP. |
1435 | 1446 | |
1436 | 1447 | The first time you start GAP from Sage, it saves the startup state |
1437 | | of GAP in the file |
1438 | | |
1439 | | :: |
1440 | | |
1441 | | $HOME/.sage/gap-workspace |
1442 | | |
| 1448 | of GAP in a file ``$HOME/.sage/gap/workspace-HASH``, where ``HASH`` |
| 1449 | is a hash of the directory where Sage is installed. |
1443 | 1450 | |
1444 | 1451 | This is useful, since then subsequent startup of GAP is at least 10 |
1445 | 1452 | times as fast. Unfortunately, if you install any new code for GAP, |
… |
… |
|
1449 | 1456 | The packages sonata, guava, factint, gapdoc, grape, design, toric, |
1450 | 1457 | and laguna are loaded in all cases before the workspace is saved, |
1451 | 1458 | if they are available. |
| 1459 | |
| 1460 | TESTS: |
| 1461 | |
| 1462 | Check that the race condition from :trac:`14242` has been fixed. |
| 1463 | We temporarily need to change the worksheet filename. :: |
| 1464 | |
| 1465 | sage: ORIGINAL_WORKSPACE = sage.interfaces.gap.WORKSPACE |
| 1466 | sage: sage.interfaces.gap.WORKSPACE = tmp_filename() |
| 1467 | sage: from multiprocessing import Process |
| 1468 | sage: import time |
| 1469 | sage: gap = Gap() # long time (reset GAP session) |
| 1470 | sage: P = [Process(target=gap, args=("14242",)) for i in range(4)] |
| 1471 | sage: for p in P: # long time, indirect doctest |
| 1472 | ... p.start() |
| 1473 | ... time.sleep(0.2) |
| 1474 | sage: for p in P: # long time |
| 1475 | ... p.join() |
| 1476 | sage: os.unlink(sage.interfaces.gap.WORKSPACE) # long time |
| 1477 | sage: sage.interfaces.gap.WORKSPACE = ORIGINAL_WORKSPACE |
1452 | 1478 | """ |
1453 | | if os.path.exists(WORKSPACE): |
1454 | | os.unlink(WORKSPACE) |
1455 | | |
1456 | 1479 | # Delete all gap workspaces that haven't been used in the last |
1457 | 1480 | # week, to avoid needless cruft. I had an install on sage.math |
1458 | 1481 | # with 90 of these, since I run a lot of different versions of |
diff --git a/sage/interfaces/interface.py b/sage/interfaces/interface.py
a
|
b
|
|
516 | 516 | return ParentWithBase.__getattribute__(self, attrname) |
517 | 517 | except AttributeError: |
518 | 518 | if attrname[:1] == "_": |
519 | | raise AttributeError |
| 519 | raise |
520 | 520 | return self._function_class()(self, attrname) |
521 | 521 | |
522 | 522 | def __cmp__(self, other): |