Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Smaller buffer tests, better docs, reorganized headers..

Fixed a few bugs.

Still need to check for memory leaks
  • Loading branch information...
commit 06c4402f7dc516ce4ff4bc40d123678d7984f101 1 parent eaf9f0d
@mnunberg authored
View
1  .gitignore
@@ -3,3 +3,4 @@
test-main
*.swp
uv/*
+.depend
View
20 Makefile
@@ -36,13 +36,22 @@ LDFLAGS=-L$(LIBCOUCHBASE_LIBDIR) -L. \
-Wl,-rpath=$(shell pwd)
LIBS_EXTRA=-lcurses -lcouchbase -luv
+UTIL_OBJ= util/hexdump.o util/yolog.o
-OBJECTS=read.o write.o socket.o common.o plugin-libuv.o timer.o yolog.o
+OBJECTS=read.o write.o socket.o common.o plugin-libuv.o timer.o $(UTIL_OBJ)
all: libcouchbase_libuv.so
+depend: .depend
+
+.depend: $(wildcard *.c)
+ rm -rf $@
+ $(CC) $(CFLAGS) -MM $^ >> $@
+
+include .depend
+
check: test-main
- ./test-main
+ LCB_LUV_DEBUG=1 ./test-main
check-lcb: libcouchbase_libuv.so
./run_lcb_tests.sh \
@@ -51,7 +60,7 @@ check-lcb: libcouchbase_libuv.so
$(LCB_TEST_NAME)
%.o: %.c
- $(CC) -c $(CFLAGS) -fpic -o $@ $^
+ $(CC) -c $(CFLAGS) -fpic -o $@ $<
$(LIBUV_A):
$(MAKE) -C uv/ CFLAGS+="$(COMPILE_FLAGS) -fPIC"
@@ -71,4 +80,7 @@ test-main: test/test.c test/simple_1.c libcouchbase_libuv.so
$(CC) -o $@ $(CFLAGS) $(LDFLAGS) $^
clean:
- rm -f $(OBJECTS) *.o *.so test-main
+ rm -f $(OBJECTS) *.o *.so test-main .depend
+
+clean-all: clean
+ $(MAKE) -C $(LIBUV_SRC) clean
View
23 README.pod
@@ -383,18 +383,33 @@ and the plugin, libcouchbase-libuv.so
To run basic async mode tests, you can do C<make check>.
-If it terminates something like:
-
+This is an example of a successful invocation (mind the exit error).
+ $ make check
+ # ...
[simple1] get_callback:30 Get callback successful
[common] lcb_luv_update_event:246 Requested events 2
[test] stop_callback:15 stop_event_loop(). Will invoke next state
[simple1] t00_contcb_next:68 Exiting now..
make: *** [check] Error 1
-then you are in the clear. Anything else is an error.
To run libcouchbase with the libuv event loop, run C<make check-lcb>.
-There will be lots of output, but hopefully none of the tests should fail.
+ $ make check-lcb
+
+ # lots of output here.
+ # ..
+ ===================
+ All 14 tests passed
+ ===================
+
+To run a specific test from within the libcouchbase test suite, you can set
+the C<LCB_TEST_NAME> Make variable, as so:
+
+ $ make check-lcb LCB_TEST_NAME=arithmetic-test
+ Will try to use loop: libuv
+ # successful termination.
+
+To get more verbose output, set C<LCB_LUV_DEBUG> in the environment.
View
13 common.c
@@ -1,6 +1,6 @@
#include "lcb_luv_internal.h"
-YOLOG_STATIC_INIT("common", YOLOG_DEBUG);
+YOLOG_STATIC_INIT("common", YOLOG_INFO);
static void
maybe_callout(lcb_luv_socket_t sock)
@@ -25,9 +25,9 @@ maybe_callout(lcb_luv_socket_t sock)
yolog_debug("Will determine if we need to call any functions..");
yolog_debug("which=%x, wait for=%x", which, sock->event->lcb_events);
if (which) {
- yolog_debug("Invoking callback for %d", sock->idx);
+ yolog_info(" ==== CB Invoking callback for %d =====", sock->idx);
sock->event->lcb_cb(sock->idx, which, sock->event->lcb_arg);
- yolog_debug("Done invoking callback for %d", sock->idx);
+ yolog_info("==== CB Done invoking callback for %d =====", sock->idx);
lcb_luv_flush(sock);
}
@@ -37,6 +37,7 @@ static void
prepare_cb(uv_prepare_t *handle, int status)
{
lcb_luv_socket_t sock = (lcb_luv_socket_t)handle->data;
+ yolog_err("prepcb start");
if (!sock) {
fprintf(stderr, "We were called with prepare_t %p, with a missing socket\n",
handle);
@@ -46,12 +47,14 @@ prepare_cb(uv_prepare_t *handle, int status)
lcb_luv_socket_ref(sock);
maybe_callout(sock);
lcb_luv_socket_unref(sock);
+ yolog_err("prepcb stop");
}
void
lcb_luv_schedule_enable(lcb_luv_socket_t sock)
{
if (sock->prep_active) {
+ yolog_debug("prep_active is true");
return;
}
@@ -65,8 +68,10 @@ void
lcb_luv_schedule_disable(lcb_luv_socket_t sock)
{
if (sock->prep_active == 0) {
+ yolog_debug("prep_active is false");
return;
}
+ yolog_debug("Disabling prepare");
uv_prepare_stop(&sock->prep);
lcb_luv_socket_unref(sock);
sock->prep_active = 0;
@@ -147,6 +152,8 @@ lcb_luv_socket_deinit(lcb_luv_socket_t sock)
return;
}
+ yolog_warn("Deinitializing socket %d", sock->idx);
+
lcb_luv_schedule_disable(sock);
if (sock->event && sock->event->handle == sock) {
View
109 lcb_luv_internal.h
@@ -7,17 +7,121 @@
#include <string.h>
#include <assert.h>
#include <errno.h>
-#include "yolog.h"
+#include "util/yolog.h"
#define EVSTATE_IS(p, b) \
( ( (p)->flags ) & LCB_LUV_EVf_ ## b)
+#define EVSTATE_FIND(sock, evtype) \
+ (sock->evstate + LCB_LUV_EV_ ## evtype)
+
+#define SOCK_EV_ENABLED(sock, evtype) \
+ (sock->event && (sock->event->lcb_events & LIBCOUCHBASE_ ## evtype ## _EVENT))
+
#define IOPS_COOKIE(iops) \
((struct lcb_luv_cookie_st*)(iops->cookie))
#define MINIMUM(a,b) \
((a < b) ? a : b)
+/**
+ * Fields representing various events
+ */
+enum {
+ LCB_LUV_EV_READ = 0,
+ LCB_LUV_EV_WRITE = 1,
+
+ LCB_LUV_EV_RDWR_MAX = 2,
+
+ LCB_LUV_EV_CONNECT = 2,
+ LCB_LUV_EV_MAX
+};
+
+
+/**
+ * Structure representing an event
+ */
+struct lcb_luv_event_st {
+ /* socket */
+ lcb_luv_socket_t handle;
+
+ /* libcouchbase function to be invoked */
+ lcb_luv_callback_t lcb_cb;
+ /* argument to pass to callback */
+ void *lcb_arg;
+
+ /* which events to monitor */
+ short lcb_events;
+};
+
+typedef enum {
+ LCB_LUV_EVf_CONNECTED = 1 << 0,
+ LCB_LUV_EVf_ACTIVE = 1 << 1,
+
+ LCB_LUV_EVf_PENDING = 1 << 2,
+ LCB_LUV_EVf_FLUSHING = 1 << 3,
+} lcb_luv_evstate_flags_t;
+
+
+
+
+struct lcb_luv_evstate_st {
+ lcb_luv_evstate_flags_t flags;
+ /* Recorded errno */
+ int err;
+};
+
+/**
+ * Structure representing a TCP network connection.
+ */
+struct lcb_luv_socket_st {
+ /* Should be first */
+ uv_tcp_t tcp;
+
+ /* Union for our requests */
+ union uv_any_req u_req;
+
+ /* Index into the 'fd' table */
+ long idx;
+
+ int eof;
+
+ uv_prepare_t prep;
+ int prep_active;
+
+ unsigned long refcount;
+
+ struct {
+ /* Readahead buffer*/
+ uv_buf_t buf;
+ char data[LCB_LUV_READAHEAD];
+ size_t pos;
+ size_t nb;
+ int readhead_active;
+ } read;
+
+ struct {
+ uv_buf_t buf;
+ /* how much data does our buffer have */
+ char data[LCB_LUV_WRITEBUFSZ];
+ size_t pos;
+ size_t nb;
+ } write;
+
+
+
+ /* various information on different operations */
+ struct lcb_luv_evstate_st evstate[LCB_LUV_EV_MAX];
+
+ /* Pointer to libcouchbase opaque event, if any */
+ struct lcb_luv_event_st *event;
+
+ /* Pointer to our cookie */
+ struct lcb_luv_cookie_st *parent;
+};
+
+
+
void *
lcb_luv_create_event(struct libcouchbase_io_opt_st *iops);
@@ -165,4 +269,7 @@ lcb_luv_schedule_enable(lcb_luv_socket_t sock);
void
lcb_luv_flush(lcb_luv_socket_t sock);
+void
+lcb_luv_hexdump(void* data, int size);
+
#endif /* LCB_LUV_INTERNAL_H_ */
View
128 libcouchbase-libuv.h
@@ -1,27 +1,26 @@
#ifndef LIBCOUCHBASE_LIBUV_H_
#define LIBCOUCHBASE_LIBUV_H_
+/* <sys/types.h> needed for size_t used in couchbase.h */
#include <sys/types.h>
+
#include <libcouchbase/couchbase.h>
#include <uv.h>
-/* The amount of data we should pre-read */
-#define LCB_LUV_READAHEAD 0x2000
-#define LCB_LUV_WRITEBUFSZ 0x2000
-
-enum {
- LCB_LUV_EV_READ = 0,
- LCB_LUV_EV_WRITE = 1,
-
- LCB_LUV_EV_RDWR_MAX = 2,
-
- LCB_LUV_EV_CONNECT = 2,
- LCB_LUV_EV_MAX
-};
+/* These variables define how much our read-ahead and write buffers
+ * should be. Do not make these too low, but setting them to insanely
+ * low amounts (for testing) should be nice. I've seen them work with
+ * as little as 0x80.
+ *
+ * The size is static and not expanded, for each socket.
+ */
+#define LCB_LUV_READAHEAD 0x4000
+#define LCB_LUV_WRITEBUFSZ 0x4000
typedef void (*lcb_luv_callback_t)(libcouchbase_socket_t,short,void*);
struct lcb_luv_socket_st;
typedef struct lcb_luv_socket_st* lcb_luv_socket_t;
+
struct lcb_luv_cookie_st;
typedef void (*lcb_luv_start_cb_t)(struct lcb_luv_cookie_st *luv_cookie);
@@ -31,107 +30,40 @@ typedef void (*lcb_luv_stop_cb_t)(struct lcb_luv_cookie_st *luv_cookie);
* Structure we place inside the iops. This is usually global per-event loop
*/
struct lcb_luv_cookie_st {
-
- /* private */
+ /* Private. Don't modify these or rely on them for meaning */
uv_loop_t *loop;
lcb_luv_socket_t *socktable;
uint16_t fd_next;
uint16_t fd_max;
-
int do_stop;
- /* public */
+ /* --- Public --- */
+
+ /* Data, put anything you want here */
void *data;
+
+ /* These two functions will be called whenever
+ * libcouchbase calls io->run_event_loop and io_stop_event_loop,
+ * respectively
+ */
lcb_luv_start_cb_t start_callback;
lcb_luv_stop_cb_t stop_callback;
};
/**
- * Structure representing an event
+ * Create a new IO operation structure.
+ *
+ * @param loop The libuv loop (can be obtained normally via uv_default_loop())
+ * @param sock_max - The maximum amount of concurrent 'sockets' to be open.
+ * sock_max * sizeof(char*) bytes are allocated per cookie you create, so you
+ * probably don't want to make it too large. 8092 or such is a safe bet.
*/
-struct lcb_luv_event_st {
- /* socket */
- lcb_luv_socket_t handle;
-
- /* libcouchbase function to be invoked */
- lcb_luv_callback_t lcb_cb;
- /* argument to pass to callback */
- void *lcb_arg;
-
- /* which events to monitor */
- short lcb_events;
-};
-
-typedef enum {
- LCB_LUV_EVf_CONNECTED = 1 << 0,
- LCB_LUV_EVf_ACTIVE = 1 << 1,
-
- LCB_LUV_EVf_PENDING = 1 << 2,
- LCB_LUV_EVf_FLUSHING = 1 << 3,
-} lcb_luv_evstate_flags_t;
-
-
-
-
-struct lcb_luv_evstate_st {
- lcb_luv_evstate_flags_t flags;
- /* Recorded errno */
- int err;
-};
+struct libcouchbase_io_opt_st *
+lcb_luv_create_io_opts(uv_loop_t *loop, uint16_t sock_max);
/**
- * Structure representing a TCP network connection.
+ * This macro 'safely' extracts and casts the cookie from the iops.
*/
-struct lcb_luv_socket_st {
- /* Should be first */
- uv_tcp_t tcp;
-
- /* Union for our requests */
- union uv_any_req u_req;
-
- /* Index into the 'fd' table */
- long idx;
-
- int eof;
-
- uv_prepare_t prep;
- int prep_active;
-
- unsigned long refcount;
-
- struct {
- /* Readahead buffer*/
- uv_buf_t buf;
- char data[LCB_LUV_READAHEAD];
- size_t pos;
- size_t nb;
- int readhead_active;
- } read;
-
- struct {
- uv_buf_t buf;
- /* how much data does our buffer have */
- char data[LCB_LUV_WRITEBUFSZ];
- size_t pos;
- size_t nb;
- } write;
-
-
-
- /* various information on different operations */
- struct lcb_luv_evstate_st evstate[LCB_LUV_EV_MAX];
-
- /* Pointer to libcouchbase opaque event, if any */
- struct lcb_luv_event_st *event;
-
- /* Pointer to our cookie */
- struct lcb_luv_cookie_st *parent;
-};
-
-
-
-struct libcouchbase_io_opt_st *
-lcb_luv_create_io_opts(uv_loop_t *loop, uint16_t sock_max);
#define lcb_luv_from_iops(iops) \
(struct lcb_luv_cookie_st *)(iops->cookie)
View
4 plugin-libuv.c
@@ -1,5 +1,5 @@
#include "lcb_luv_internal.h"
-
+YOLOG_STATIC_INIT("plugin", YOLOG_DEBUG);
static void lcb_luv_noop(struct libcouchbase_io_opt_st *iops)
{
(void)iops;
@@ -28,6 +28,7 @@ invoke_stop_callback(struct libcouchbase_io_opt_st *iops)
static void sync_loop_run(struct libcouchbase_io_opt_st *iops)
{
+ yolog_info("=== LOOP: run ===");
IOPS_COOKIE(iops)->do_stop = 0;
while (IOPS_COOKIE(iops)->do_stop == 0) {
uv_run_once(IOPS_COOKIE(iops)->loop);
@@ -36,6 +37,7 @@ static void sync_loop_run(struct libcouchbase_io_opt_st *iops)
static void sync_loop_stop(struct libcouchbase_io_opt_st *iops)
{
+ yolog_info("=== LOOP: stop ===");
IOPS_COOKIE(iops)->do_stop = 1;
}
View
10 read.c
@@ -1,5 +1,5 @@
#include "lcb_luv_internal.h"
-YOLOG_STATIC_INIT("read", YOLOG_DEBUG);
+YOLOG_STATIC_INIT("read", YOLOG_WARN);
uv_buf_t
alloc_cb(uv_handle_t *handle, size_t suggested_size)
@@ -15,6 +15,7 @@ read_cb(uv_stream_t *stream, ssize_t nread, uv_buf_t buf)
lcb_luv_socket_t sock = (lcb_luv_socket_t)stream;
int is_stopped = 0;
lcb_luv_socket_ref(sock);
+ yolog_debug("%d: nr=%d, len=%d", sock->idx, nread, buf.len);
if (nread == -1) {
uv_err_t last_err = uv_last_error(sock->parent->loop);
@@ -56,6 +57,7 @@ lcb_luv_read_nudge(lcb_luv_socket_t sock)
{
int status;
if (sock->read.readhead_active) {
+ yolog_debug("Read-ahead already active");
return; /* nothing to do here */
}
@@ -67,6 +69,7 @@ lcb_luv_read_nudge(lcb_luv_socket_t sock)
yolog_err("Couldn't start read: %d",
sock->evstate[LCB_LUV_EV_READ].err);
} else {
+ yolog_debug("read-ahead initialized");
sock->read.buf.len = LCB_LUV_READAHEAD;
sock->read.buf.base = sock->read.data;
lcb_luv_socket_ref(sock);
@@ -80,7 +83,7 @@ lcb_luv_read_stop(lcb_luv_socket_t sock)
if (sock->read.readhead_active == 0) {
return;
}
- uv_read_stop(&sock->tcp);
+ uv_read_stop((uv_stream_t*)&sock->tcp);
sock->read.readhead_active = 0;
lcb_luv_socket_unref(sock);
}
@@ -94,7 +97,8 @@ read_common(lcb_luv_socket_t sock, void *buffer, libcouchbase_size_t len,
libcouchbase_ssize_t ret;
size_t read_offset, toRead;
-// yolog_debug("%p: Requested to read %d bytes into %p", sock, len, buffer);
+ yolog_debug("%d: Requested to read %d bytes. have %d",
+ sock->idx, len, sock->read.nb);
/* basic error checking */
View
4 run_lcb_tests.sh
@@ -4,6 +4,8 @@ LIBCOUCHBASE_LIBDIR=$2
TEST_NAME=$3
export LIBCOUCHBASE_VERBOSE_TESTS=1
+export LIBCOUCHBASE_DEBUG=100
+export LIBCOUCHBASE_DEBUG_COLORS=1
export LIBCOUCHBASE_TEST_LOOP="libuv"
export LD_LIBRARY_PATH="$PWD:$LIBCOUCHBASE_SRC/.libs:$LD_LIBRARY_PATH"
@@ -15,5 +17,5 @@ if [ -z "$TEST_NAME" ]; then
make -C $LIBCOUCHBASE_SRC/ check
else
cd $LIBCOUCHBASE_SRC/
- $DEBUGGER ./tests/.libs/$TEST_NAME
+ $DEBUGGER ./tests/$TEST_NAME
fi
View
2  socket.c
@@ -1,6 +1,6 @@
#include "lcb_luv_internal.h"
-YOLOG_STATIC_INIT("socket", YOLOG_DEBUG);
+YOLOG_STATIC_INIT("socket", YOLOG_WARN);
View
2  test/lcb_luv_test.h
@@ -2,7 +2,7 @@
#define LCB_LUV_TEST_H_
#include "libcouchbase-libuv.h"
-#include "../yolog.h"
+#include "../util/yolog.h"
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
View
58 util/hexdump.c
@@ -0,0 +1,58 @@
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+void lcb_luv_hexdump(void *data, int size)
+{
+ /* dumps size bytes of *data to stdout. Looks like:
+ * [0000] 75 6E 6B 6E 6F 77 6E 20
+ * 30 FF 00 00 00 00 39 00 unknown 0.....9.
+ * (in a single line of course)
+ */
+
+ unsigned char *p = data;
+ unsigned char c;
+ int n;
+ char bytestr[4] = {0};
+ char addrstr[10] = {0};
+ char hexstr[ 16*3 + 5] = {0};
+ char charstr[16*1 + 5] = {0};
+ for(n=1;n<=size;n++) {
+ if (n%16 == 1) {
+ /* store address for this line */
+ snprintf(addrstr, sizeof(addrstr), "%.4x",
+ ((unsigned int)p-(unsigned int)data) );
+ }
+
+ c = *p;
+ if (isalnum(c) == 0) {
+ c = '.';
+ }
+
+ /* store hex str (for left side) */
+ snprintf(bytestr, sizeof(bytestr), "%02X ", *p);
+ strncat(hexstr, bytestr, sizeof(hexstr)-strlen(hexstr)-1);
+
+ /* store char str (for right side) */
+ snprintf(bytestr, sizeof(bytestr), "%c", c);
+ strncat(charstr, bytestr, sizeof(charstr)-strlen(charstr)-1);
+
+ if(n%16 == 0) {
+ /* line completed */
+ printf("[%4.4s] %-50.50s %s\n", addrstr, hexstr, charstr);
+ hexstr[0] = 0;
+ charstr[0] = 0;
+ } else if(n%8 == 0) {
+ /* half line: add whitespaces */
+ strncat(hexstr, " ", sizeof(hexstr)-strlen(hexstr)-1);
+ strncat(charstr, " ", sizeof(charstr)-strlen(charstr)-1);
+ }
+ p++; /* next byte */
+ }
+
+ if (strlen(hexstr) > 0) {
+ /* print rest of buffer if not empty */
+ printf("[%4.4s] %-50.50s %s\n", addrstr, hexstr, charstr);
+ }
+}
+
View
31 yolog.c → util/yolog.c
@@ -34,10 +34,15 @@ static yobot_log_s loggerparams_internal = {
};
static char *title_fmt = "", *reset_fmt = "";
+static int LoggingEnabled = 0;
#ifdef HAVE_CURSES
static int use_escapes = -1;
static void _init_color_logging(void) {
+ char *tmp = getenv("LCB_LUV_DEBUG");
+ if (tmp && *tmp) {
+ LoggingEnabled = 1;
+ }
if (use_escapes < 0) {
if (!isatty(STDOUT_FILENO)) {
use_escapes = 0;
@@ -110,17 +115,19 @@ void yobot_logger(yobot_log_s logparams, yobot_log_level level, int line,
break;
}
}
- flockfile(stdout);
- printf("[%s%s%s] ", title_fmt, logparams.prefix, reset_fmt);
-#ifdef YOLOG_TIME
- printf(" %f ", (float)clock()/CLOCKS_PER_SEC);
-#endif
- printf("%s", line_fmt);
- printf("%s:%d ", fn, line);
- vprintf(fmt, ap);
- printf("%s", reset_fmt);
- printf("\n");
- fflush(NULL);
- funlockfile(stdout);
+ if (LoggingEnabled) {
+ flockfile(stdout);
+ printf("[%s%s%s] ", title_fmt, logparams.prefix, reset_fmt);
+ #ifdef YOLOG_TIME
+ printf(" %f ", (float)clock()/CLOCKS_PER_SEC);
+ #endif
+ printf("%s", line_fmt);
+ printf("%s:%d ", fn, line);
+ vprintf(fmt, ap);
+ printf("%s", reset_fmt);
+ printf("\n");
+ fflush(NULL);
+ funlockfile(stdout);
+ }
va_end(ap);
}
View
0  yolog.h → util/yolog.h
File renamed without changes
View
57 write.c
@@ -13,24 +13,33 @@ static void
write_cb(uv_write_t *req, int status)
{
lcb_luv_socket_t sock = (lcb_luv_socket_t)req->data;
+ struct lcb_luv_evstate_st *evstate;
+
if (!sock) {
fprintf(stderr, "Got write callback (req=%p) without socket\n", req);
return;
}
+
+ evstate = EVSTATE_FIND(sock, WRITE);
+
if (status) {
- sock->evstate[LCB_LUV_EV_WRITE].err =
- (uv_last_error(sock->parent->loop)).code;
+ evstate->err = (uv_last_error(sock->parent->loop)).code;
}
-
- yolog_err("Wrote all our data: status=%d", status);
+ yolog_debug("Flush done. Flushed %d bytes", sock->write.buf.len);
sock->write.pos = 0;
sock->write.nb = 0;
- sock->evstate[LCB_LUV_EV_WRITE].flags |= LCB_LUV_EVf_PENDING;
- sock->evstate[LCB_LUV_EV_WRITE].flags &= ~(LCB_LUV_EVf_FLUSHING);
- if (sock->event->lcb_events & LIBCOUCHBASE_WRITE_EVENT) {
- sock->event->lcb_cb(sock->idx, LIBCOUCHBASE_WRITE_EVENT,
- sock->event->lcb_arg);
+ evstate->flags |= LCB_LUV_EVf_PENDING;
+ evstate->flags &= ~(LCB_LUV_EVf_FLUSHING);
+
+ if (SOCK_EV_ENABLED(sock, WRITE)) {
+ sock->event->lcb_cb(sock->idx, LIBCOUCHBASE_WRITE_EVENT, sock->event->lcb_arg);
+
+ if (sock->write.nb) {
+ evstate->flags &= ~(LCB_LUV_EVf_PENDING);
+ lcb_luv_flush(sock);
+ }
}
+
lcb_luv_socket_unref(sock);
}
@@ -42,32 +51,29 @@ void
lcb_luv_flush(lcb_luv_socket_t sock)
{
int status;
-
+ struct lcb_luv_evstate_st *evstate;
if (sock->write.nb == 0) {
- yolog_warn("%d: Nothing to flush..", sock->idx);
return;
}
- if (sock->evstate[LCB_LUV_EV_WRITE].flags & LCB_LUV_EVf_FLUSHING) {
+ evstate = EVSTATE_FIND(sock, WRITE);
+ if(EVSTATE_IS(evstate, FLUSHING)) {
yolog_warn("Not flushing because we are in the middle of a flush");
return;
}
sock->write.buf.base = sock->write.data;
sock->write.buf.len = sock->write.nb;
-
+ yolog_debug("Will flush");
status = uv_write(&sock->u_req.write,
(uv_stream_t*)&sock->tcp,
&sock->write.buf, 1, write_cb);
lcb_luv_socket_ref(sock);
- yolog_warn("%d: Requested to flush %d bytes", sock->idx, sock->write.buf.len);
-
if (status) {
- sock->evstate[LCB_LUV_EV_WRITE].err =
- (uv_last_error(sock->parent->loop)).code;
+ evstate->err = (uv_last_error(sock->parent->loop)).code;
}
- sock->evstate[LCB_LUV_EV_WRITE].flags |= LCB_LUV_EVf_FLUSHING;
+ evstate->flags |= LCB_LUV_EVf_FLUSHING;
}
@@ -75,30 +81,37 @@ static libcouchbase_ssize_t
write_common(lcb_luv_socket_t sock, const void *buf, size_t len, int *errno_out)
{
libcouchbase_ssize_t ret;
- struct lcb_luv_evstate_st *evstate = sock->evstate + LCB_LUV_EV_WRITE;
- yolog_warn("%d: Requested to write %d bytes from %p", sock->idx, len, buf);
+ struct lcb_luv_evstate_st *evstate = EVSTATE_FIND(sock, WRITE);
+
+ yolog_debug("%d: Requested to write %d bytes from %p", sock->idx, len, buf);
if (evstate->err) {
+ yolog_warn("Socket has pending error %d", evstate->err);
*errno_out = evstate->err;
evstate->err = 0;
return -1;
}
- if (evstate->flags & LCB_LUV_EVf_FLUSHING) {
+ if (EVSTATE_IS(evstate, FLUSHING)) {
+ yolog_warn("Will not write because we are inside a flush");
*errno_out = EWOULDBLOCK;
return -1;
}
ret = MINIMUM(len, sizeof(sock->write.data) - sock->write.nb);
if (ret == 0) {
+ yolog_warn("We have no more space inside the buffer");
*errno_out = EWOULDBLOCK;
return -1;
}
+
+
memcpy(sock->write.data + sock->write.pos, buf, ret);
+// lcb_luv_hexdump(sock->write.data + sock->write.pos, ret);
sock->write.pos += ret;
sock->write.nb += ret;
- yolog_warn("Returning successfuly (nb=%d)", sock->write.nb);
+ yolog_debug("Returning %d", ret);
return ret;
}
Please sign in to comment.
Something went wrong with that request. Please try again.