From: Linda Sun <l...@vmware.com> Use send/recv for socket stream instead of read/write. Use event handle for polling on socket stream. Check windows specific return code.
Signed-off-by: Linda Sun <l...@vmware.com> Signed-off-by: Gurucharan Shetty <gshe...@nicira.com> --- lib/automake.mk | 7 +-- lib/{latch.c => latch-unix.c} | 0 lib/{stream-fd.c => stream-fd-unix.c} | 0 lib/{stream-fd.c => stream-fd-windows.c} | 75 ++++++++++++++++-------------- lib/stream-fd.h | 3 ++ lib/stream.c | 4 +- 6 files changed, 50 insertions(+), 39 deletions(-) rename lib/{latch.c => latch-unix.c} (100%) copy lib/{stream-fd.c => stream-fd-unix.c} (100%) rename lib/{stream-fd.c => stream-fd-windows.c} (84%) diff --git a/lib/automake.mk b/lib/automake.mk index 6c5ad8d..f3868db 100644 --- a/lib/automake.mk +++ b/lib/automake.mk @@ -188,7 +188,6 @@ lib_libopenvswitch_la_SOURCES = \ lib/sset.h \ lib/stp.c \ lib/stp.h \ - lib/stream-fd.c \ lib/stream-fd.h \ lib/stream-provider.h \ lib/stream-ssl.h \ @@ -239,11 +238,13 @@ if WIN32 lib_libopenvswitch_la_SOURCES += \ lib/daemon-windows.c \ lib/getopt_long.c \ - lib/latch-windows.c + lib/latch-windows.c \ + lib/stream-fd-windows.c else lib_libopenvswitch_la_SOURCES += \ lib/daemon.c \ - lib/latch.c \ + lib/latch-unix.c \ + lib/stream-fd-unix.c \ lib/stream-unix.c endif diff --git a/lib/latch.c b/lib/latch-unix.c similarity index 100% rename from lib/latch.c rename to lib/latch-unix.c diff --git a/lib/stream-fd.c b/lib/stream-fd-unix.c similarity index 100% copy from lib/stream-fd.c copy to lib/stream-fd-unix.c diff --git a/lib/stream-fd.c b/lib/stream-fd-windows.c similarity index 84% rename from lib/stream-fd.c rename to lib/stream-fd-windows.c index 8062d2d..06aef46 100644 --- a/lib/stream-fd.c +++ b/lib/stream-fd-windows.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2009, 2010, 2012, 2013, 2014 Nicira, Inc. + * Copyright (c) 2014 Nicira, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,18 +20,18 @@ #include <poll.h> #include <stdlib.h> #include <string.h> -#include <sys/socket.h> #include <sys/types.h> #include <unistd.h> +#include <winsock2.h> #include "fatal-signal.h" #include "poll-loop.h" #include "socket-util.h" -#include "util.h" -#include "stream-provider.h" #include "stream.h" +#include "stream-provider.h" +#include "util.h" #include "vlog.h" -VLOG_DEFINE_THIS_MODULE(stream_fd); +VLOG_DEFINE_THIS_MODULE(stream_fd_windows); /* Active file descriptor stream. */ @@ -39,14 +39,13 @@ struct stream_fd { struct stream stream; int fd; + HANDLE wevent; }; static const struct stream_class stream_fd_class; static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(10, 25); -static void maybe_unlink_and_free(char *path); - /* Creates a new stream named 'name' that will send and receive data on 'fd' * and stores a pointer to the stream in '*streamp'. Initial connection status * 'connect_status' is interpreted as described for stream_init(). @@ -62,6 +61,7 @@ new_fd_stream(const char *name, int fd, int connect_status, s = xmalloc(sizeof *s); stream_init(&s->stream, &stream_fd_class, connect_status, name); s->fd = fd; + s->wevent = CreateEvent(NULL, FALSE, FALSE, NULL); *streamp = &s->stream; return 0; } @@ -77,7 +77,9 @@ static void fd_close(struct stream *stream) { struct stream_fd *s = stream_fd_cast(stream); - close(s->fd); + WSAEventSelect(s->fd, NULL, 0); + CloseHandle(s->wevent); + closesocket(s->fd); free(s); } @@ -94,8 +96,14 @@ fd_recv(struct stream *stream, void *buffer, size_t n) struct stream_fd *s = stream_fd_cast(stream); ssize_t retval; - retval = read(s->fd, buffer, n); - return retval >= 0 ? retval : -errno; + retval = recv(s->fd, buffer, n, 0); + if (retval < 0) { + retval = -sock_errno(); + } + if (retval == -WSAEWOULDBLOCK) { + return -EAGAIN; + } + return retval; } static ssize_t @@ -104,10 +112,15 @@ fd_send(struct stream *stream, const void *buffer, size_t n) struct stream_fd *s = stream_fd_cast(stream); ssize_t retval; - retval = write(s->fd, buffer, n); - return (retval > 0 ? retval - : retval == 0 ? -EAGAIN - : -errno); + retval = send(s->fd, buffer, n, 0); + if (retval < 0) { + retval = -sock_errno(); + } + if (retval == -WSAEWOULDBLOCK) { + return -EAGAIN; + } + + return retval; } static void @@ -117,15 +130,15 @@ fd_wait(struct stream *stream, enum stream_wait_type wait) switch (wait) { case STREAM_CONNECT: case STREAM_SEND: - poll_fd_wait(s->fd, POLLOUT); + poll_fd_wait_event(s->fd, s->wevent, POLLOUT); break; case STREAM_RECV: - poll_fd_wait(s->fd, POLLIN); + poll_fd_wait_event(s->fd, s->wevent, POLLIN); break; default: - OVS_NOT_REACHED(); + NOT_REACHED(); } } @@ -148,6 +161,7 @@ struct fd_pstream { struct pstream pstream; int fd; + HANDLE wevent; int (*accept_cb)(int fd, const struct sockaddr_storage *, size_t ss_len, struct stream **); int (*set_dscp_cb)(int fd, uint8_t dscp); @@ -187,6 +201,7 @@ new_fd_pstream(const char *name, int fd, struct fd_pstream *ps = xmalloc(sizeof *ps); pstream_init(&ps->pstream, &fd_pstream_class, name); ps->fd = fd; + ps->wevent = CreateEvent(NULL, FALSE, FALSE, NULL); ps->accept_cb = accept_cb; ps->set_dscp_cb = set_dscp_cb; ps->unlink_path = unlink_path; @@ -198,8 +213,9 @@ static void pfd_close(struct pstream *pstream) { struct fd_pstream *ps = fd_pstream_cast(pstream); - close(ps->fd); - maybe_unlink_and_free(ps->unlink_path); + WSAEventSelect(ps->fd, NULL, 0); + CloseHandle(ps->wevent); + closesocket(ps->fd); free(ps); } @@ -214,16 +230,16 @@ pfd_accept(struct pstream *pstream, struct stream **new_streamp) new_fd = accept(ps->fd, (struct sockaddr *) &ss, &ss_len); if (new_fd < 0) { - retval = errno; - if (retval != EAGAIN) { - VLOG_DBG_RL(&rl, "accept: %s", ovs_strerror(retval)); + retval = sock_errno(); + if (retval == WSAEWOULDBLOCK) { + return EAGAIN; } return retval; } retval = set_nonblocking(new_fd); if (retval) { - close(new_fd); + closesocket(new_fd); return retval; } @@ -234,7 +250,7 @@ static void pfd_wait(struct pstream *pstream) { struct fd_pstream *ps = fd_pstream_cast(pstream); - poll_fd_wait(ps->fd, POLLIN); + poll_fd_wait_event(ps->fd, ps->wevent, POLLIN); } static int @@ -256,13 +272,4 @@ static const struct pstream_class fd_pstream_class = { pfd_wait, pfd_set_dscp, }; - -/* Helper functions. */ -static void -maybe_unlink_and_free(char *path) -{ - if (path) { - fatal_signal_unlink_file_now(path); - free(path); - } -} + diff --git a/lib/stream-fd.h b/lib/stream-fd.h index 8f595a9..9f138a7 100644 --- a/lib/stream-fd.h +++ b/lib/stream-fd.h @@ -12,6 +12,9 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * Note on windows platform, stream fd can only handle sockets, on unix any + * fd is acceptable. */ #ifndef STREAM_FD_H diff --git a/lib/stream.c b/lib/stream.c index 2e7accb..1dfecf0 100644 --- a/lib/stream.c +++ b/lib/stream.c @@ -51,7 +51,7 @@ enum stream_state { static const struct stream_class *stream_classes[] = { &tcp_stream_class, -#ifdef AF_UNIX +#ifndef _WIN32 &unix_stream_class, #endif #ifdef HAVE_OPENSSL @@ -61,7 +61,7 @@ static const struct stream_class *stream_classes[] = { static const struct pstream_class *pstream_classes[] = { &ptcp_pstream_class, -#ifdef AF_UNIX +#ifndef _WIN32 &punix_pstream_class, #endif #ifdef HAVE_OPENSSL -- 1.7.9.5 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev