From 7c07a68b653b63575717efec00595818f25b9410 Mon Sep 17 00:00:00 2001 From: albert Date: Mon, 4 Sep 2017 12:33:35 +0200 Subject: [PATCH] Fix #56, undo uniqueid patch The `uniqueid` module had a bug when "imported" with the RepyV1 preprocessor, `repypp`. (That program had no notion of modules already imported, so it would paste multiple copies of imported libraries and thus cause duplicate IDs with the `uniqueid` module). This bug was patched for V1, but the patch never removed since. In RepyV2, `dylink` is used to import modules, and it does a much better job at importing modules only once, see for instance SeattleTestbed/seattlelib_v2#55. Therefore, we can remove the old patch! To verify that removing the patch is safe, I also added a unit test that checks `uniqueid`'s * basic functionality, * functioning after reimport, and * function across threads. --- tests/ut_seattlelib_uniqueidbasictest.r2py | 44 ++++++++++++++++++++++ uniqueid.r2py | 16 ++------ 2 files changed, 47 insertions(+), 13 deletions(-) create mode 100644 tests/ut_seattlelib_uniqueidbasictest.r2py diff --git a/tests/ut_seattlelib_uniqueidbasictest.r2py b/tests/ut_seattlelib_uniqueidbasictest.r2py new file mode 100644 index 0000000..0df3490 --- /dev/null +++ b/tests/ut_seattlelib_uniqueidbasictest.r2py @@ -0,0 +1,44 @@ +""" +Check that uniqueid returns unique ids, also if imported multiple times, +and across multiple threads. +""" +#pragma repy restrictions.default dylink.r2py + +uniqueid = dy_import_module("uniqueid.r2py") + + +# Test 1: Get a couple of IDs and see if they are indeed unique. + +oldids = [] + +for i in range(100): + newid = uniqueid.uniqueid_getid() + assert newid not in oldids, "Saw the same ID twice: " + str(oldid) + oldids.append(newid) + + + +# Test 2: "Reimport" the library. (Dylink should yield the existing instance.) + +uniqueid2 = dy_import_module("uniqueid.r2py") + +assert uniqueid2.uniqueid_getid() != uniqueid.uniqueid_getid(), "Got the same ID twice after pseudo-reimporting!" + + + +# Test 3: Get IDs in threads + +idlist = [] + +def get_an_id(): + idlist.append(uniqueid.uniqueid_getid()) + +for i in range(10): + createthread(get_an_id) + +# Give the threads some time to spawn and finish +sleep(5) + +for anid in idlist: + assert idlist.count(anid)==1, "Duplicate ID: " + str(anid) + diff --git a/uniqueid.r2py b/uniqueid.r2py index f1a485b..b65ad2f 100644 --- a/uniqueid.r2py +++ b/uniqueid.r2py @@ -7,20 +7,12 @@ Start date: November 11th, 2008 This is a really, really simple module, only broken out to avoid duplicating functionality. - -NOTE: This will give unique ids PER FILE. If you have multiple python -modules that include this, they will have the potential to generate the -same ID. - """ -# This is a list to prevent using part of the user's mycontext dict -# We use getruntime() instead of a list starting with 0, as this -# library may get imported multiple times. -# See ticket #1319 and #1318 for more details. +# Use this list as module-level storage. (This avoids cluttering the +# programmer's `mycontext` dict.) -current_time = getruntime() -uniqueid_idlist = [int((current_time - int(current_time)) * 2**32)] +uniqueid_idlist = [0] uniqueid_idlock = createlock() @@ -44,8 +36,6 @@ def uniqueid_getid(): uniqueid_idlock.acquire(True) - # I'm using a list because I need a global, but don't want to use the - # programmer's dict myid = uniqueid_idlist[0] uniqueid_idlist[0] = uniqueid_idlist[0] + 1