*/
#include "includes.h"
-#include "events.h"
-#include "dlinklist.h"
+#include "lib/events/events.h"
+#include "lib/util/dlinklist.h"
#include "vfs_posix.h"
#include "smbd/service_stream.h"
+#include "lib/messaging/irpc.h"
/* the context for a single wait instance */
struct pvfs_wait {
struct pvfs_state *pvfs;
void (*handler)(void *, enum pvfs_wait_notice);
void *private;
- struct timed_event *te;
int msg_type;
struct messaging_context *msg_ctx;
struct event_context *ev;
- struct smbsrv_request *req;
+ struct ntvfs_request *req;
enum pvfs_wait_notice reason;
};
previous ntvfs handlers in the chain (such as security context)
*/
NTSTATUS pvfs_async_setup(struct ntvfs_module_context *ntvfs,
- struct smbsrv_request *req, void *private)
+ struct ntvfs_request *req, void *private)
{
struct pvfs_wait *pwait = private;
pwait->handler(pwait->private, pwait->reason);
uint32_t src, DATA_BLOB *data)
{
struct pvfs_wait *pwait = private;
- struct smbsrv_request *req;
+ struct ntvfs_request *req;
/* we need to check that this one is for us. See
messaging_send_ptr() for the other side of this.
receive a timeout on a message wait
*/
static void pvfs_wait_timeout(struct event_context *ev,
- struct timed_event *te, struct timeval t)
+ struct timed_event *te, struct timeval t, void *private)
{
- struct pvfs_wait *pwait = te->private;
- struct smbsrv_request *req = pwait->req;
+ struct pvfs_wait *pwait = talloc_get_type(private, struct pvfs_wait);
+ struct ntvfs_request *req = pwait->req;
pwait->reason = PVFS_WAIT_TIMEOUT;
/*
destroy a pending wait
*/
-static int pvfs_wait_destructor(void *ptr)
+static int pvfs_wait_destructor(struct pvfs_wait *pwait)
{
- struct pvfs_wait *pwait = ptr;
- messaging_deregister(pwait->msg_ctx, pwait->msg_type, pwait);
+ if (pwait->msg_type != -1) {
+ messaging_deregister(pwait->msg_ctx, pwait->msg_type, pwait);
+ }
DLIST_REMOVE(pwait->pvfs->wait_list, pwait);
return 0;
}
the return value is a handle. To stop waiting talloc_free this
handle.
+
+ if msg_type == -1 then no message is registered, and it is assumed
+ that the caller handles any messaging setup needed
*/
- void *pvfs_wait_message(struct pvfs_state *pvfs,
- struct smbsrv_request *req,
+void *pvfs_wait_message(struct pvfs_state *pvfs,
+ struct ntvfs_request *req,
int msg_type,
struct timeval end_time,
void (*fn)(void *, enum pvfs_wait_notice),
void *private)
{
- struct timed_event te;
struct pvfs_wait *pwait;
pwait = talloc(pvfs, struct pvfs_wait);
pwait->private = private;
pwait->handler = fn;
- pwait->msg_ctx = pvfs->tcon->smb_conn->connection->msg_ctx;
- pwait->ev = req->tcon->smb_conn->connection->event.ctx;
+ pwait->msg_ctx = pvfs->ntvfs->ctx->msg_ctx;
+ pwait->ev = pvfs->ntvfs->ctx->event_ctx;
pwait->msg_type = msg_type;
pwait->req = talloc_reference(pwait, req);
pwait->pvfs = pvfs;
- /* setup a timer */
- te.next_event = end_time;
- te.handler = pvfs_wait_timeout;
- te.private = pwait;
- pwait->te = event_add_timed(pwait->ev, &te, pwait);
+ if (!timeval_is_zero(&end_time)) {
+ /* setup a timer */
+ event_add_timed(pwait->ev, pwait, end_time, pvfs_wait_timeout, pwait);
+ }
/* register with the messaging subsystem for this message
type */
- messaging_register(pwait->msg_ctx,
- pwait,
- msg_type,
- pvfs_wait_dispatch);
+ if (msg_type != -1) {
+ messaging_register(pwait->msg_ctx,
+ pwait,
+ msg_type,
+ pvfs_wait_dispatch);
+ }
/* tell the main smb server layer that we will be replying
asynchronously */
/*
cancel an outstanding async request
*/
-NTSTATUS pvfs_cancel(struct ntvfs_module_context *ntvfs, struct smbsrv_request *req)
+NTSTATUS pvfs_cancel(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req)
{
struct pvfs_state *pvfs = ntvfs->private_data;
struct pvfs_wait *pwait;
+
for (pwait=pvfs->wait_list;pwait;pwait=pwait->next) {
- if (SVAL(req->in.hdr, HDR_MID) == SVAL(pwait->req->in.hdr, HDR_MID) &&
- req->smbpid == pwait->req->smbpid) {
+ if (pwait->req == req) {
/* trigger a cancel on the request */
pwait->reason = PVFS_WAIT_CANCEL;
ntvfs_async_setup(pwait->req, pwait);
}
}
- return NT_STATUS_UNSUCCESSFUL;
+ return NT_STATUS_DOS(ERRDOS, ERRcancelviolation);
}