summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2013-03-20 18:40:05 -0400
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2015-07-05 14:19:18 -0400
commit8057e1c7e7213011157a05a2e6ee467a204c0b71 (patch)
tree1b0604db348a5de16281f752f9c89ddf73f0df83
parentf55e2d9049f79834a35164545616faac8fea07fc (diff)
downloadpython-systemd-8057e1c7e7213011157a05a2e6ee467a204c0b71.tar.gz
systemd-python: cleanup up usec_t handling
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.
-rw-r--r--systemd/_reader.c39
-rw-r--r--systemd/journal.py20
2 files changed, 28 insertions, 31 deletions
diff --git a/systemd/_reader.c b/systemd/_reader.c
index 17c0015..4fe7847 100644
--- a/systemd/_reader.c
+++ b/systemd/_reader.c
@@ -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"
- "`realtime` can must be an integer unix timestamp.");
+ "`realtime` in specified in seconds.");
static PyObject* Reader_seek_realtime(Reader *self, PyObject *args)
{
- double timedouble;
uint64_t timestamp;
int r;
- if (!PyArg_ParseTuple(args, "d:_Reader.seek_realtime", &timedouble))
+ if (!PyArg_ParseTuple(args, "K:seek_realtime", &timestamp))
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
@@ -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"
- "`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)
{
- double timedouble;
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;
- }
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_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"
- "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.");
-static PyObject* Reader_wait(Reader *self, PyObject *args, PyObject *keywds)
+static PyObject* Reader_wait(Reader *self, PyObject *args)
{
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
- 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;
diff --git a/systemd/journal.py b/systemd/journal.py
index fee39c9..a522aec 100644
--- a/systemd/journal.py
+++ b/systemd/journal.py
@@ -51,10 +51,10 @@ def _convert_source_monotonic(s):
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):
- return _datetime.datetime.fromtimestamp(int(s) / 1E6)
+ return _datetime.datetime.fromtimestamp(int(s) / 1000000)
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))
+ 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.
@@ -216,8 +227,8 @@ class Reader(_Reader):
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.
@@ -229,6 +240,7 @@ class Reader(_Reader):
"""
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)