TODO:better name? tsocket: add tsocket_context infrastructure
authorStefan Metzmacher <metze@samba.org>
Fri, 3 Apr 2009 14:12:21 +0000 (16:12 +0200)
committerStefan Metzmacher <metze@samba.org>
Mon, 22 Apr 2013 09:12:53 +0000 (11:12 +0200)
This one only takes care accept_send/recv().

metze

lib/tsocket/tsocket.c
lib/tsocket/tsocket.h
lib/tsocket/tsocket_internal.h

index 674858de0a5aa416c6ee92cdd7d464a117c76c7b..86736e21e827dd1baf30e56951ff8cd41514dbd8 100644 (file)
@@ -810,3 +810,203 @@ int tstream_disconnect_recv(struct tevent_req *req,
        return ret;
 }
 
+struct tsocket_context {
+       const char *location;
+       const struct tsocket_context_ops *ops;
+       void *private_data;
+};
+
+struct tsocket_context *_tsocket_context_create(TALLOC_CTX *mem_ctx,
+                                       const struct tsocket_context_ops *ops,
+                                       void *pstate,
+                                       size_t psize,
+                                       const char *type,
+                                       const char *location)
+{
+       struct tsocket_context *sock;
+       void **ppstate = (void **)pstate;
+       void *state;
+
+       sock = talloc(mem_ctx, struct tsocket_context);
+       if (sock == NULL) {
+               return NULL;
+       }
+       sock->location  = location;
+       sock->ops       = ops;
+
+       state = talloc_size(sock, psize);
+       if (state == NULL) {
+               talloc_free(sock);
+               return NULL;
+       }
+       talloc_set_name_const(state, type);
+
+       sock->private_data = state;
+
+       *ppstate = state;
+       return sock;
+}
+
+void *_tsocket_context_data(struct tsocket_context *sock)
+{
+       return sock->private_data;
+}
+
+struct tsocket_accept_state {
+       const struct tsocket_context_ops *ops;
+       struct tsocket_address *local;
+       struct tsocket_address *remote;
+       struct tstream_context *stream;
+};
+
+static void tsocket_accept_done(struct tevent_req *subreq);
+
+struct tevent_req *tsocket_accept_send(TALLOC_CTX *mem_ctx,
+                                      struct tevent_context *ev,
+                                      struct tsocket_context *sock)
+{
+       struct tevent_req *req;
+       struct tsocket_accept_state *state;
+       struct tevent_req *subreq;
+
+       req = tevent_req_create(mem_ctx, &state,
+                               struct tsocket_accept_state);
+       if (req == NULL) {
+               return NULL;
+       }
+
+       state->ops = sock->ops;
+       state->local = NULL;
+       state->remote = NULL;
+       state->stream = NULL;
+
+       subreq = state->ops->accept_send(state, ev, sock);
+       if (tevent_req_nomem(subreq, req)) {
+               goto post;
+       }
+       tevent_req_set_callback(subreq, tsocket_accept_done, req);
+
+       return req;
+
+ post:
+       tevent_req_post(req, ev);
+       return req;
+}
+
+static void tsocket_accept_done(struct tevent_req *subreq)
+{
+       struct tevent_req *req = tevent_req_callback_data(subreq,
+                                struct tevent_req);
+       struct tsocket_accept_state *state = tevent_req_data(req,
+                                            struct tsocket_accept_state);
+       ssize_t ret;
+       int sys_errno;
+
+       ret = state->ops->accept_recv(subreq, &sys_errno,
+                                     state,
+                                     &state->local,
+                                     &state->remote,
+                                     &state->stream,
+                                     "tsocket_accept_done");
+       if (ret == -1) {
+               tevent_req_error(req, sys_errno);
+               return;
+       }
+
+       tevent_req_done(req);
+}
+
+int _tsocket_accept_recv(struct tevent_req *req,
+                        int *perrno,
+                        TALLOC_CTX *mem_ctx,
+                        struct tsocket_address **local,
+                        struct tsocket_address **remote,
+                        struct tstream_context **stream,
+                        const char *location)
+{
+       struct tsocket_accept_state *state = tevent_req_data(req,
+                                            struct tsocket_accept_state);
+       int ret;
+
+       ret = tsocket_simple_int_recv(req, perrno);
+       if (ret == 0) {
+               if (local) {
+                       state->local->location = location;
+                       *local = talloc_move(mem_ctx, &state->local);
+               }
+               if (remote) {
+                       state->remote->location = location;
+                       *remote = talloc_move(mem_ctx, &state->remote);
+               }
+               state->stream->location = location;
+               *stream = talloc_move(mem_ctx, &state->stream);
+       }
+
+       tevent_req_received(req);
+       return ret;
+}
+
+struct tsocket_shutdown_state {
+       const struct tsocket_context_ops *ops;
+};
+
+static void tsocket_shutdown_done(struct tevent_req *subreq);
+
+struct tevent_req *tsocket_shutdown_send(TALLOC_CTX *mem_ctx,
+                                        struct tevent_context *ev,
+                                        struct tsocket_context *sock)
+{
+       struct tevent_req *req;
+       struct tsocket_shutdown_state *state;
+       struct tevent_req *subreq;
+
+       req = tevent_req_create(mem_ctx, &state,
+                               struct tsocket_shutdown_state);
+       if (req == NULL) {
+               return NULL;
+       }
+
+       state->ops = sock->ops;
+
+       subreq = state->ops->shutdown_send(state, ev, sock);
+       if (tevent_req_nomem(subreq, req)) {
+               goto post;
+       }
+       tevent_req_set_callback(subreq, tsocket_shutdown_done, req);
+
+       return req;
+
+ post:
+       tevent_req_post(req, ev);
+       return req;
+}
+
+static void tsocket_shutdown_done(struct tevent_req *subreq)
+{
+       struct tevent_req *req = tevent_req_callback_data(subreq,
+                                struct tevent_req);
+       struct tsocket_shutdown_state *state = tevent_req_data(req,
+                                              struct tsocket_shutdown_state);
+       int ret;
+       int sys_errno;
+
+       ret = state->ops->shutdown_recv(subreq, &sys_errno);
+       if (ret == -1) {
+               tevent_req_error(req, sys_errno);
+               return;
+       }
+
+       tevent_req_done(req);
+}
+
+int tsocket_shutdown_recv(struct tevent_req *req,
+                         int *perrno)
+{
+       int ret;
+
+       ret = tsocket_simple_int_recv(req, perrno);
+
+       tevent_req_received(req);
+       return ret;
+}
+
index 98f864e6a570c7e4f6261708215563c51e4d8c17..c231fff7a588b55d520071c4e30bb6959ce4d04f 100644 (file)
@@ -30,6 +30,7 @@
 struct tsocket_address;
 struct tdgram_context;
 struct tstream_context;
+struct tsocket_context;
 struct iovec;
 
 /**
@@ -1153,5 +1154,28 @@ int tstream_writev_queue_recv(struct tevent_req *req, int *perrno);
  * @}
  */
 
+/*
+ * tsocket_context related functions
+ */
+struct tevent_req *tsocket_accept_send(TALLOC_CTX *mem_ctx,
+                                      struct tevent_context *ev,
+                                      struct tsocket_context *sock);
+int _tsocket_accept_recv(struct tevent_req *req,
+                        int *perrno,
+                        TALLOC_CTX *mem_ctx,
+                        struct tsocket_address **local,
+                        struct tsocket_address **remote,
+                        struct tstream_context **stream,
+                        const char *location);
+#define tsocket_accept_recv(req, perrno, mem_ctx, local, remote, stream) \
+       _tsocket_accept_recv(req, perrno, mem_ctx, local, remote, stream, \
+                            __location__)
+
+struct tevent_req *tsocket_shutdown_send(TALLOC_CTX *mem_ctx,
+                                        struct tevent_context *ev,
+                                        struct tsocket_context *sock);
+int tsocket_shutdown_recv(struct tevent_req *req,
+                         int *perrno);
+
 #endif /* _TSOCKET_H */
 
index 154b2ce6f890c66b0cdc6643f1bdabfdd5447dbe..952615ac413871c96b78323cf49f67d3086e6671 100644 (file)
@@ -138,6 +138,41 @@ void *_tstream_context_data(struct tstream_context *stream);
 #define tstream_context_data(_req, _type) \
        talloc_get_type_abort(_tstream_context_data(_req), _type)
 
+struct tsocket_context_ops {
+       const char *name;
+
+       struct tevent_req *(*accept_send)(TALLOC_CTX *mem_ctx,
+                                         struct tevent_context *ev,
+                                         struct tsocket_context *sock);
+       int (*accept_recv)(struct tevent_req *req,
+                          int *perrno,
+                          TALLOC_CTX *mem_ctx,
+                          struct tsocket_address **local,
+                          struct tsocket_address **remote,
+                          struct tstream_context **stream,
+                          const char *location);
+
+       struct tevent_req *(*shutdown_send)(TALLOC_CTX *mem_ctx,
+                                           struct tevent_context *ev,
+                                           struct tsocket_context *sock);
+       int (*shutdown_recv)(struct tevent_req *req,
+                            int *perrno);
+};
+
+struct tsocket_context *_tsocket_context_create(TALLOC_CTX *mem_ctx,
+                                       const struct tsocket_context_ops *ops,
+                                       void *pstate,
+                                       size_t psize,
+                                       const char *type,
+                                       const char *location);
+#define tsocket_context_create(mem_ctx, ops, state, type, location) \
+       _tsocket_context_create(mem_ctx, ops, state, sizeof(type), \
+                               #type, location)
+
+void *_tsocket_context_data(struct tsocket_context *sock);
+#define tsocket_context_data(_req, _type) \
+       talloc_get_type_abort(_tstream_server_data(_req), _type)
+
 int tsocket_simple_int_recv(struct tevent_req *req, int *perrno);
 
 #endif /* _TSOCKET_H */