[Zope-Checkins] CVS: Zope3/lib/python/ZODB - TimeStamp.c:1.8.4.3

Jeremy Hylton jeremy@zope.com
Wed, 5 Dec 2001 12:21:34 -0500


Update of /cvs-repository/Zope3/lib/python/ZODB
In directory cvs.zope.org:/tmp/cvs-serv9357/lib/python/ZODB

Modified Files:
      Tag: Zope-3x-branch
	TimeStamp.c 
Log Message:
Replace use of global variables with struct.

The TimeStamp_load_statics() function unpacked the internal
representation and stored it in four global ints.  This was presumably
safe because of the global interpreter lock, but a potential risk.
The function was changed to TimeStamp_unpack() and takes a pointer to
a TimeStampParts struct as its second argument.  It assigns to slots
in the struct instead of using global variables.

Also reformat some code to use 4-space tabs consistently.


=== Zope3/lib/python/ZODB/TimeStamp.c 1.8.4.2 => 1.8.4.3 ===
 TimeStamp_compare(TimeStamp *v, TimeStamp *w)
 {
-  return memcmp(v->data, w->data, 8);
+    return memcmp(v->data, w->data, 8);
 }
 
 static long
 TimeStamp_hash(TimeStamp *self)
 {
-	register unsigned char *p = (unsigned char *)self->data;
-	register int len = 8;
-	register long x = *p << 7;
-	/* XXX unroll loop? */
-	while (--len >= 0)
-		x = (1000003*x) ^ *p++;
-	x ^= 8;
-	if (x == -1)
-		x = -2;
-	return x;
-}
-
-/* XXX only thread-safe in presence of global interpreter lock */
-static int TimeStamp_y, TimeStamp_m, TimeStamp_d, TimeStamp_mi;
-
+    register unsigned char *p = (unsigned char *)self->data;
+    register int len = 8;
+    register long x = *p << 7;
+    /* XXX unroll loop? */
+    while (--len >= 0)
+	x = (1000003*x) ^ *p++;
+    x ^= 8;
+    if (x == -1)
+	x = -2;
+    return x;
+}
+
+typedef struct {
+    int y, m, d, mi;
+} TimeStampParts;
+  
 static void 
-TimeStamp_load_statics(TimeStamp *self)
+TimeStamp_unpack(TimeStamp *self, TimeStampParts *p)
 {
-  unsigned long v;
+    unsigned long v;
 
-  v = (self->data[0] * 16777216 + self->data[1] * 65536 
-       + self->data[2] * 256 + self->data[3]);
-  TimeStamp_y = v / 535680 + 1900;
-  TimeStamp_m = (v % 535680) / 44640 + 1;
-  TimeStamp_d = (v % 44640) / 1440 + 1;
-  TimeStamp_mi = v % 1440;
+    v = (self->data[0] * 16777216 + self->data[1] * 65536 
+	 + self->data[2] * 256 + self->data[3]);
+    p->y = v / 535680 + 1900;
+    p->m = (v % 535680) / 44640 + 1;
+    p->d = (v % 44640) / 1440 + 1;
+    p->mi = v % 1440;
 }
 
 static double
 TimeStamp_sec(TimeStamp *self)
 {
-  unsigned int v;
+    unsigned int v;
 
-  v = (self->data[4] * 16777216 + self->data[5] * 65536
-       + self->data[6] * 256 + self->data[7]);
-  return SCONV * v;
+    v = (self->data[4] * 16777216 + self->data[5] * 65536
+	 + self->data[6] * 256 + self->data[7]);
+    return SCONV * v;
 }
 
 static PyObject *
 TimeStamp_year(TimeStamp *self)
 {
-    TimeStamp_load_statics(self);
-    return PyInt_FromLong(TimeStamp_y);
+    TimeStampParts p;
+    TimeStamp_unpack(self, &p);
+    return PyInt_FromLong(p.y);
 }
 
 static PyObject *
 TimeStamp_month(TimeStamp *self)
 {
-    TimeStamp_load_statics(self);
-    return PyInt_FromLong(TimeStamp_m);
+    TimeStampParts p;
+    TimeStamp_unpack(self, &p);
+    return PyInt_FromLong(p.m);
 }
 
 static PyObject *
 TimeStamp_day(TimeStamp *self)
 {
-    TimeStamp_load_statics(self);
-    return PyInt_FromLong(TimeStamp_d);
+    TimeStampParts p;
+    TimeStamp_unpack(self, &p);
+    return PyInt_FromLong(p.d);
 }
 
 static PyObject *
 TimeStamp_hour(TimeStamp *self)
 {
-    TimeStamp_load_statics(self);
-    return PyInt_FromLong(TimeStamp_mi / 60);
+    TimeStampParts p;
+    TimeStamp_unpack(self, &p);
+    return PyInt_FromLong(p.mi / 60);
 }
 
 static PyObject *
 TimeStamp_minute(TimeStamp *self)
 {
-    TimeStamp_load_statics(self);
-    return PyInt_FromLong(TimeStamp_mi % 60);
+    TimeStampParts p;
+    TimeStamp_unpack(self, &p);
+    return PyInt_FromLong(p.mi % 60);
 }
 
 static PyObject *
@@ -194,9 +200,9 @@
 static PyObject *
 TimeStamp_timeTime(TimeStamp *self)
 {
-    TimeStamp_load_statics(self);
-    return PyFloat_FromDouble(TimeStamp_abst(TimeStamp_y, TimeStamp_m - 1,
-					     TimeStamp_d - 1, TimeStamp_mi, 0)
+    TimeStampParts p;
+    TimeStamp_unpack(self, &p);
+    return PyFloat_FromDouble(TimeStamp_abst(p.y, p.m - 1, p.d - 1, p.mi, 0)
 			      + TimeStamp_sec(self) - gmoff);
 }
 
@@ -210,6 +216,7 @@
 TimeStamp_laterThan(TimeStamp *self, PyObject *obj)
 {
     TimeStamp *o = NULL;
+    TimeStampParts p;
     unsigned char new[8];
     int i;
 
@@ -235,23 +242,22 @@
 
     /* All but the first two bytes are the same.  Need to increment
        the year, month, and day explicitly. */
-    TimeStamp_load_statics(o);
-    if (TimeStamp_mi >= 1439) {
-	TimeStamp_mi = 0;
-	if (TimeStamp_d == month_len[leap(TimeStamp_y)][TimeStamp_m - 1]) {
-	    TimeStamp_d = 1;
-	    if (TimeStamp_m == 12) {
-		TimeStamp_m = 1;
-		TimeStamp_y++;
+    TimeStamp_unpack(o, &p);
+    if (p.mi >= 1439) {
+	p.mi = 0;
+	if (p.d == month_len[leap(p.y)][p.m - 1]) {
+	    p.d = 1;
+	    if (p.m == 12) {
+		p.m = 1;
+		p.y++;
 	    } else
-		TimeStamp_m++;
+		p.m++;
 	} else
-	    TimeStamp_d++;
+	    p.d++;
     } else
-	TimeStamp_mi++;
+	p.mi++;
 
-    return TimeStamp_FromDate(TimeStamp_y, TimeStamp_m, TimeStamp_d,
-			      TimeStamp_mi / 60, TimeStamp_mi % 60, 0);
+    return TimeStamp_FromDate(p.y, p.m, p.d, p.mi / 60, p.mi % 60, 0);
 }
 
 static struct PyMethodDef TimeStamp_methods[] = {
@@ -268,41 +274,41 @@
 };
 
 static PyTypeObject TimeStamp_type = {
-	PyObject_HEAD_INIT(NULL)
-	0,
-	"TimeStamp",
-	sizeof(TimeStamp),
-	0,
-	(destructor)TimeStamp_dealloc,		/* tp_dealloc */
-	0,					/* tp_print */
-	0,					/* tp_getattr */
-	0,					/* tp_setattr */
-	(cmpfunc)TimeStamp_compare,		/* tp_compare */
-	0,					/* tp_repr */
-	0,					/* tp_as_number */
-	0,					/* tp_as_sequence */
-	0,					/* tp_as_mapping */
-	(hashfunc)TimeStamp_hash,		/* tp_hash */
-	0,					/* tp_call */
-	0,					/* tp_str */
-	0,					/* tp_getattro */
-	0,					/* tp_setattro */
-	0,					/* tp_as_buffer */
-	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
-	0,					/* tp_doc */
-	0,					/* tp_traverse */
-	0,					/* tp_clear */
-	0,					/* tp_richcompare */
-	0,					/* tp_weaklistoffset */
-	0,					/* tp_iter */
-	0,					/* tp_iternext */
-	TimeStamp_methods,			/* tp_methods */
-	0,			/* tp_members */
-	0,					/* tp_getset */
-	0,				/* tp_base */
-	0,					/* tp_dict */
-	0,					/* tp_descr_get */
-	0,					/* tp_descr_set */
+    PyObject_HEAD_INIT(NULL)
+    0,
+    "TimeStamp",
+    sizeof(TimeStamp),
+    0,
+    (destructor)TimeStamp_dealloc,	/* tp_dealloc */
+    0,					/* tp_print */
+    0,					/* tp_getattr */
+    0,					/* tp_setattr */
+    (cmpfunc)TimeStamp_compare,		/* tp_compare */
+    0,					/* tp_repr */
+    0,					/* tp_as_number */
+    0,					/* tp_as_sequence */
+    0,					/* tp_as_mapping */
+    (hashfunc)TimeStamp_hash,		/* tp_hash */
+    0,					/* tp_call */
+    0,					/* tp_str */
+    0,					/* tp_getattro */
+    0,					/* tp_setattro */
+    0,					/* tp_as_buffer */
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
+    0,					/* tp_doc */
+    0,					/* tp_traverse */
+    0,					/* tp_clear */
+    0,					/* tp_richcompare */
+    0,					/* tp_weaklistoffset */
+    0,					/* tp_iter */
+    0,					/* tp_iternext */
+    TimeStamp_methods,			/* tp_methods */
+    0,					/* tp_members */
+    0,					/* tp_getset */
+    0,					/* tp_base */
+    0,					/* tp_dict */
+    0,					/* tp_descr_get */
+    0,					/* tp_descr_set */
 };
 
 PyObject *