1
0
mirror of https://github.com/samba-team/samba.git synced 2025-01-13 13:18:06 +03:00

s3-pylibsmb: Add get_oplock_break

Autobuild-User(master): Volker Lendecke <vl@samba.org>
Autobuild-Date(master): Sun Sep 23 18:01:28 CEST 2012 on sn-devel-104
This commit is contained in:
Volker Lendecke 2012-09-22 10:45:32 -07:00
parent ff6840815d
commit 9e6070b5fc

View File

@ -70,11 +70,20 @@ static int ParseTupleAndKeywords(PyObject *args, PyObject *kw,
struct py_cli_thread;
struct py_cli_oplock_break {
uint16_t fnum;
uint8_t level;
};
struct py_cli_state {
PyObject_HEAD
struct cli_state *cli;
struct tevent_context *ev;
struct py_cli_thread *thread_state;
struct tevent_req *oplock_waiter;
struct py_cli_oplock_break *oplock_breaks;
struct py_tevent_cond *oplock_cond;
};
#if HAVE_PTHREAD
@ -377,9 +386,14 @@ static PyObject *py_cli_state_new(PyTypeObject *type, PyObject *args,
self->cli = NULL;
self->ev = NULL;
self->thread_state = NULL;
self->oplock_waiter = NULL;
self->oplock_cond = NULL;
self->oplock_breaks = NULL;
return (PyObject *)self;
}
static void py_cli_got_oplock_break(struct tevent_req *req);
static int py_cli_state_init(struct py_cli_state *self, PyObject *args,
PyObject *kwds)
{
@ -429,12 +443,116 @@ static int py_cli_state_init(struct py_cli_state *self, PyObject *args,
PyErr_SetNTSTATUS(status);
return -1;
}
self->oplock_waiter = cli_smb_oplock_break_waiter_send(
self->ev, self->ev, self->cli);
if (self->oplock_waiter == NULL) {
PyErr_NoMemory();
return -1;
}
tevent_req_set_callback(self->oplock_waiter, py_cli_got_oplock_break,
self);
return 0;
}
static void py_cli_got_oplock_break(struct tevent_req *req)
{
struct py_cli_state *self = (struct py_cli_state *)
tevent_req_callback_data_void(req);
struct py_cli_oplock_break b;
struct py_cli_oplock_break *tmp;
size_t num_breaks;
NTSTATUS status;
status = cli_smb_oplock_break_waiter_recv(req, &b.fnum, &b.level);
TALLOC_FREE(req);
self->oplock_waiter = NULL;
if (!NT_STATUS_IS_OK(status)) {
return;
}
num_breaks = talloc_array_length(self->oplock_breaks);
tmp = talloc_realloc(self->ev, self->oplock_breaks,
struct py_cli_oplock_break, num_breaks+1);
if (tmp == NULL) {
return;
}
self->oplock_breaks = tmp;
self->oplock_breaks[num_breaks] = b;
if (self->oplock_cond != NULL) {
py_tevent_cond_signal(self->oplock_cond);
}
self->oplock_waiter = cli_smb_oplock_break_waiter_send(
self->ev, self->ev, self->cli);
if (self->oplock_waiter == NULL) {
return;
}
tevent_req_set_callback(self->oplock_waiter, py_cli_got_oplock_break,
self);
}
static PyObject *py_cli_get_oplock_break(struct py_cli_state *self,
PyObject *args)
{
size_t num_oplock_breaks;
if (!PyArg_ParseTuple(args, "")) {
return NULL;
}
if (self->oplock_cond != NULL) {
errno = EBUSY;
PyErr_SetFromErrno(PyExc_RuntimeError);
return NULL;
}
num_oplock_breaks = talloc_array_length(self->oplock_breaks);
if (num_oplock_breaks == 0) {
struct py_tevent_cond cond;
int ret;
self->oplock_cond = &cond;
ret = py_tevent_cond_wait(&cond);
self->oplock_cond = NULL;
if (ret != 0) {
errno = ret;
PyErr_SetFromErrno(PyExc_RuntimeError);
return NULL;
}
}
num_oplock_breaks = talloc_array_length(self->oplock_breaks);
if (num_oplock_breaks > 0) {
PyObject *result;
result = Py_BuildValue(
"{s:i,s:i}",
"fnum", self->oplock_breaks[0].fnum,
"level", self->oplock_breaks[0].level);
memmove(&self->oplock_breaks[0], &self->oplock_breaks[1],
sizeof(self->oplock_breaks[0]) *
(num_oplock_breaks - 1));
self->oplock_breaks = talloc_realloc(
NULL, self->oplock_breaks, struct py_cli_oplock_break,
num_oplock_breaks - 1);
return result;
}
Py_INCREF(Py_None);
return Py_None;
}
static void py_cli_state_dealloc(struct py_cli_state *self)
{
TALLOC_FREE(self->thread_state);
TALLOC_FREE(self->oplock_waiter);
TALLOC_FREE(self->ev);
if (self->cli != NULL) {
@ -737,6 +855,8 @@ static PyMethodDef py_cli_state_methods[] = {
{ "readdir", (PyCFunction)py_cli_list,
METH_VARARGS|METH_KEYWORDS,
"List a directory" },
{ "get_oplock_break", (PyCFunction)py_cli_get_oplock_break,
METH_VARARGS, "Wait for an oplock break" },
{ NULL, NULL, 0, NULL }
};