chiark / gitweb /
systemd-python: cleanup up usec_t handling
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Wed, 20 Mar 2013 22:40:05 +0000 (18:40 -0400)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Fri, 22 Mar 2013 02:39:24 +0000 (22:39 -0400)
The behaviour wrt. seconds vs. microseconds was inconsistent.
Now _Reader always uses native units (us), while Reader always
uses seconds and accepts both floats and ints. This way the
conversion is always done in the Python layer, and the lower
level API allows access to the journal API without the potentially
lossy conversion between double and uint64_t.

src/python-systemd/_reader.c
src/python-systemd/journal.py

index 17c0015..4fe7847 100644 (file)
@@ -499,22 +499,15 @@ static PyObject* Reader_seek_tail(Reader *self, PyObject *args)
 PyDoc_STRVAR(Reader_seek_realtime__doc__,
              "seek_realtime(realtime) -> None\n\n"
              "Seek to nearest matching journal entry to `realtime`. Argument\n"
 PyDoc_STRVAR(Reader_seek_realtime__doc__,
              "seek_realtime(realtime) -> None\n\n"
              "Seek to nearest matching journal entry to `realtime`. Argument\n"
-             "`realtime` can must be an integer unix timestamp.");
+             "`realtime` in specified in seconds.");
 static PyObject* Reader_seek_realtime(Reader *self, PyObject *args)
 {
 static PyObject* Reader_seek_realtime(Reader *self, PyObject *args)
 {
-    double timedouble;
     uint64_t timestamp;
     int r;
 
     uint64_t timestamp;
     int r;
 
-    if (!PyArg_ParseTuple(args, "d:_Reader.seek_realtime", &timedouble))
+    if (!PyArg_ParseTuple(args, "K:seek_realtime", &timestamp))
         return NULL;
 
         return NULL;
 
-    timestamp = (uint64_t) (timedouble * 1.0E6);
-    if ((int64_t) timestamp < 0LL) {
-        PyErr_SetString(PyExc_ValueError, "Time must be a positive integer");
-        return NULL;
-    }
-
     Py_BEGIN_ALLOW_THREADS
     r = sd_journal_seek_realtime_usec(self->j, timestamp);
     Py_END_ALLOW_THREADS
     Py_BEGIN_ALLOW_THREADS
     r = sd_journal_seek_realtime_usec(self->j, timestamp);
     Py_END_ALLOW_THREADS
@@ -527,26 +520,18 @@ static PyObject* Reader_seek_realtime(Reader *self, PyObject *args)
 PyDoc_STRVAR(Reader_seek_monotonic__doc__,
              "seek_monotonic(monotonic[, bootid]) -> None\n\n"
              "Seek to nearest matching journal entry to `monotonic`. Argument\n"
 PyDoc_STRVAR(Reader_seek_monotonic__doc__,
              "seek_monotonic(monotonic[, bootid]) -> None\n\n"
              "Seek to nearest matching journal entry to `monotonic`. Argument\n"
-             "`monotonic` is an timestamp from boot in seconds.\n"
+             "`monotonic` is an timestamp from boot in microseconds.\n"
              "Argument `bootid` is a string representing which boot the\n"
              "monotonic time is reference to. Defaults to current bootid.");
 static PyObject* Reader_seek_monotonic(Reader *self, PyObject *args)
 {
              "Argument `bootid` is a string representing which boot the\n"
              "monotonic time is reference to. Defaults to current bootid.");
 static PyObject* Reader_seek_monotonic(Reader *self, PyObject *args)
 {
-    double timedouble;
     char *bootid = NULL;
     uint64_t timestamp;
     sd_id128_t id;
     int r;
 
     char *bootid = NULL;
     uint64_t timestamp;
     sd_id128_t id;
     int r;
 
-    if (!PyArg_ParseTuple(args, "d|z:_Reader.seek_monotonic", &timedouble, &bootid))
-        return NULL;
-
-    timestamp = (uint64_t) (timedouble * 1.0E6);
-
-    if ((int64_t) timestamp < 0LL) {
-        PyErr_SetString(PyExc_ValueError, "Time must be positive number");
+    if (!PyArg_ParseTuple(args, "K|z:seek_monotonic", &timestamp, &bootid))
         return NULL;
         return NULL;
-    }
 
     if (bootid) {
         r = sd_id128_from_string(bootid, &id);
 
     if (bootid) {
         r = sd_id128_from_string(bootid, &id);
@@ -565,6 +550,7 @@ static PyObject* Reader_seek_monotonic(Reader *self, PyObject *args)
     Py_END_ALLOW_THREADS
     if (set_error(r, NULL, NULL))
         return NULL;
     Py_END_ALLOW_THREADS
     if (set_error(r, NULL, NULL))
         return NULL;
+
     Py_RETURN_NONE;
 }
 
     Py_RETURN_NONE;
 }
 
@@ -572,23 +558,22 @@ static PyObject* Reader_seek_monotonic(Reader *self, PyObject *args)
 PyDoc_STRVAR(Reader_wait__doc__,
              "wait([timeout]) -> state change (integer)\n\n"
              "Wait for a change in the journal. Argument `timeout` specifies\n"
 PyDoc_STRVAR(Reader_wait__doc__,
              "wait([timeout]) -> state change (integer)\n\n"
              "Wait for a change in the journal. Argument `timeout` specifies\n"
-             "the maximum number of seconds to wait before returning\n"
-             "regardless of wheter the journal has changed. If `timeout` is not given\n"
-             "or is 0, then block forever.\n"
+             "the maximum number of microseconds to wait before returning\n"
+             "regardless of wheter the journal has changed. If `timeout` is -1,\n"
+             "then block forever.\n\n"
              "Will return constants: NOP if no change; APPEND if new\n"
              "entries have been added to the end of the journal; and\n"
              "INVALIDATE if journal files have been added or removed.");
              "Will return constants: NOP if no change; APPEND if new\n"
              "entries have been added to the end of the journal; and\n"
              "INVALIDATE if journal files have been added or removed.");
-static PyObject* Reader_wait(Reader *self, PyObject *args, PyObject *keywds)
+static PyObject* Reader_wait(Reader *self, PyObject *args)
 {
     int r;
 {
     int r;
-    int64_t timeout = 0LL;
+    int64_t timeout;
 
 
-    if (!PyArg_ParseTuple(args, "|L:_Reader.wait", &timeout))
+    if (!PyArg_ParseTuple(args, "|L:wait", &timeout))
         return NULL;
 
     Py_BEGIN_ALLOW_THREADS
         return NULL;
 
     Py_BEGIN_ALLOW_THREADS
-    r = sd_journal_wait(self->j,
-                        timeout == 0 ? (uint64_t) -1 : timeout * 1E6);
+    r = sd_journal_wait(self->j, timeout);
     Py_END_ALLOW_THREADS
     if (set_error(r, NULL, NULL) < 0)
         return NULL;
     Py_END_ALLOW_THREADS
     if (set_error(r, NULL, NULL) < 0)
         return NULL;
index fee39c9..a522aec 100644 (file)
@@ -51,10 +51,10 @@ def _convert_source_monotonic(s):
     return _datetime.timedelta(microseconds=int(s))
 
 def _convert_realtime(t):
     return _datetime.timedelta(microseconds=int(s))
 
 def _convert_realtime(t):
-    return _datetime.datetime.fromtimestamp(t / 1E6)
+    return _datetime.datetime.fromtimestamp(t / 1000000)
 
 def _convert_timestamp(s):
 
 def _convert_timestamp(s):
-    return _datetime.datetime.fromtimestamp(int(s) / 1E6)
+    return _datetime.datetime.fromtimestamp(int(s) / 1000000)
 
 if _sys.version_info >= (3,):
     def _convert_uuid(s):
 
 if _sys.version_info >= (3,):
     def _convert_uuid(s):
@@ -209,6 +209,17 @@ class Reader(_Reader):
         return set(self._convert_field(field, value)
             for value in super(Reader, self).query_unique(field))
 
         return set(self._convert_field(field, value)
             for value in super(Reader, self).query_unique(field))
 
+    def wait(self, timeout=None):
+        """Wait for a change in the journal. `timeout` is the maximum
+        time in seconds to wait, or None, to wait forever.
+
+        Returns one of NOP (no change), APPEND (new entries have been
+        added to the end of the journal), or INVALIDATE (journal files
+        have been added or removed).
+        """
+        us = -1 if timeout is None else int(timeout * 1000000)
+        return super(Reader, self).wait(timeout)
+
     def seek_realtime(self, realtime):
         """Seek to a matching journal entry nearest to `realtime` time.
 
     def seek_realtime(self, realtime):
         """Seek to a matching journal entry nearest to `realtime` time.
 
@@ -216,8 +227,8 @@ class Reader(_Reader):
         or datetime.datetime instance.
         """
         if isinstance(realtime, _datetime.datetime):
         or datetime.datetime instance.
         """
         if isinstance(realtime, _datetime.datetime):
-            realtime = float(realtime.strftime("%s.%f"))
-        return super(Reader, self).seek_realtime(realtime)
+            realtime = float(realtime.strftime("%s.%f")) * 1000000
+        return super(Reader, self).seek_realtime(int(realtime))
 
     def seek_monotonic(self, monotonic, bootid=None):
         """Seek to a matching journal entry nearest to `monotonic` time.
 
     def seek_monotonic(self, monotonic, bootid=None):
         """Seek to a matching journal entry nearest to `monotonic` time.
@@ -229,6 +240,7 @@ class Reader(_Reader):
         """
         if isinstance(monotonic, _datetime.timedelta):
             monotonic = monotonic.totalseconds()
         """
         if isinstance(monotonic, _datetime.timedelta):
             monotonic = monotonic.totalseconds()
+        monotonic = int(monotonic * 1000000)
         if isinstance(bootid, _uuid.UUID):
             bootid = bootid.get_hex()
         return super(Reader, self).seek_monotonic(monotonic, bootid)
         if isinstance(bootid, _uuid.UUID):
             bootid = bootid.get_hex()
         return super(Reader, self).seek_monotonic(monotonic, bootid)