Skip to content

Commit

Permalink
Allow the user to specify sync mode on an instance
Browse files Browse the repository at this point in the history
Change-Id: Ibe6bbcece6f8ebb67a6b38fb1bbc5fb9baafdf1e
Reviewed-on: http://review.couchbase.org/12560
Tested-by: Trond Norbye <trond.norbye@gmail.com>
Reviewed-by: Matt Ingenthron <matt@couchbase.com>
  • Loading branch information
trondn committed Jan 21, 2012
1 parent 652b6b2 commit 64e519c
Show file tree
Hide file tree
Showing 16 changed files with 185 additions and 17 deletions.
3 changes: 3 additions & 0 deletions Makefile.am
Expand Up @@ -31,6 +31,7 @@ bin_PROGRAMS = tools/cbc


pkginclude_HEADERS = \
include/libcouchbase/behavior.h \
include/libcouchbase/callbacks.h \
include/libcouchbase/configuration.h \
include/libcouchbase/couchbase.h \
Expand All @@ -44,6 +45,7 @@ pkginclude_HEADERS = \
libcouchbase_la_SOURCES = \
src/arithmetic.c \
src/base64.c \
src/behavior.c \
src/config_static.h \
src/cookie.c \
src/error.c \
Expand All @@ -62,6 +64,7 @@ libcouchbase_la_SOURCES = \
src/stats.c \
src/store.c \
src/strerror.c \
src/synchandler.c \
src/tap.c \
src/timings.c \
src/touch.c \
Expand Down
8 changes: 8 additions & 0 deletions NMakefile
Expand Up @@ -32,6 +32,7 @@ DLLCOMPILE=$(cc) $(cdebug) $(cflags) $(cvarsdll) $(DBGFLG) $(INCPATH) -DLIBCOUCH

LIBCOUCHBASE_OBJS=arithmetic.obj \
base64.obj \
behavior.obj \
cookie.obj \
error.obj \
event.obj \
Expand All @@ -49,6 +50,7 @@ LIBCOUCHBASE_OBJS=arithmetic.obj \
server.obj \
store.obj \
strerror.obj \
synchandler.obj \
tap.obj \
timings.obj \
touch.obj \
Expand Down Expand Up @@ -150,6 +152,9 @@ arithmetic.obj: src\arithmetic.c
base64.obj: src\base64.c
$(DLLCOMPILE) src\base64.c

behavior.obj: src\behavior.c
$(DLLCOMPILE) src\behavior.c

cookie.obj: src\cookie.c
$(DLLCOMPILE) src\cookie.c

Expand Down Expand Up @@ -207,6 +212,9 @@ store.obj: src\store.c
strerror.obj: src\strerror.c
$(DLLCOMPILE) src\strerror.c

synchandler.obj: src\synchandler.c
$(DLLCOMPILE) src\synchandler.c

tap.obj: src\tap.c
$(DLLCOMPILE) src\tap.c

Expand Down
40 changes: 40 additions & 0 deletions include/libcouchbase/behavior.h
@@ -0,0 +1,40 @@
/* -*- Mode: C; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
/*
* Copyright 2012 Couchbase, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* 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.
*/

#ifndef LIBCOUCHBASE_BEHAVIOR_H
#define LIBCOUCHBASE_BEHAVIOR_H 1

#ifndef LIBCOUCHBASE_COUCHBASE_H
#error "Include libcouchbase/couchbase.h instead"
#endif

#ifdef __cplusplus
extern "C" {
#endif

LIBCOUCHBASE_API
void libcouchbase_behavior_set_syncmode(libcouchbase_t instance,
libcouchbase_syncmode_t syncmode);

LIBCOUCHBASE_API
libcouchbase_syncmode_t libcouchbase_behavior_get_syncmode(libcouchbase_t instance);

#ifdef __cplusplus
}
#endif

#endif
1 change: 1 addition & 0 deletions include/libcouchbase/couchbase.h
Expand Up @@ -30,6 +30,7 @@
#include <libcouchbase/configuration.h>
#include <libcouchbase/visibility.h>
#include <libcouchbase/types.h>
#include <libcouchbase/behavior.h>
#include <libcouchbase/callbacks.h>
#include <libcouchbase/tap_filter.h>
#include <libcouchbase/timings.h>
Expand Down
5 changes: 5 additions & 0 deletions include/libcouchbase/types.h
Expand Up @@ -257,6 +257,11 @@ extern "C" {

} libcouchbase_io_opt_t;

typedef enum {
LIBCOUCHBASE_ASYNCHRONOUS = 0x00,
LIBCOUCHBASE_SYNCHRONOUS = 0xff
} libcouchbase_syncmode_t;

#ifdef __cplusplus
}
#endif
Expand Down
4 changes: 2 additions & 2 deletions src/arithmetic.c
Expand Up @@ -48,7 +48,7 @@ libcouchbase_error_t libcouchbase_arithmetic_by_key(libcouchbase_t instance,

/* we need a vbucket config before we can start getting data.. */
if (instance->vbucket_config == NULL) {
return LIBCOUCHBASE_ETMPFAIL;
return libcouchbase_synchandler_return(instance, LIBCOUCHBASE_ETMPFAIL);
}

if (nhashkey == 0) {
Expand Down Expand Up @@ -86,5 +86,5 @@ libcouchbase_error_t libcouchbase_arithmetic_by_key(libcouchbase_t instance,
libcouchbase_server_end_packet(server);
libcouchbase_server_send_packets(server);

return LIBCOUCHBASE_SUCCESS;
return libcouchbase_synchandler_return(instance, LIBCOUCHBASE_SUCCESS);
}
29 changes: 29 additions & 0 deletions src/behavior.c
@@ -0,0 +1,29 @@
/* -*- Mode: C; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
/*
* Copyright 2012 Couchbase, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* 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.
*/
#include "internal.h"

LIBCOUCHBASE_API
void libcouchbase_behavior_set_syncmode(libcouchbase_t instance, libcouchbase_syncmode_t syncmode)
{
instance->syncmode = syncmode;
}

LIBCOUCHBASE_API
libcouchbase_syncmode_t libcouchbase_behavior_get_syncmode(libcouchbase_t instance)
{
return instance->syncmode;
}
4 changes: 2 additions & 2 deletions src/flush.c
Expand Up @@ -27,7 +27,7 @@ libcouchbase_error_t libcouchbase_flush(libcouchbase_t instance,

/* we need a vbucket config before we can start getting data.. */
if (instance->vbucket_config == NULL) {
return LIBCOUCHBASE_ETMPFAIL;
return libcouchbase_synchandler_return(instance, LIBCOUCHBASE_ETMPFAIL);
}

memset(&flush, 0, sizeof(flush));
Expand All @@ -44,5 +44,5 @@ libcouchbase_error_t libcouchbase_flush(libcouchbase_t instance,
libcouchbase_server_send_packets(server);
}

return LIBCOUCHBASE_SUCCESS;
return libcouchbase_synchandler_return(instance, LIBCOUCHBASE_SUCCESS);
}
6 changes: 3 additions & 3 deletions src/get.c
Expand Up @@ -62,7 +62,7 @@ libcouchbase_error_t libcouchbase_mget_by_key(libcouchbase_t instance,

/* we need a vbucket config before we can start getting data.. */
if (instance->vbucket_config == NULL) {
return LIBCOUCHBASE_ETMPFAIL;
return libcouchbase_synchandler_return(instance, LIBCOUCHBASE_ETMPFAIL);
}

if (num_keys == 1) {
Expand Down Expand Up @@ -133,7 +133,7 @@ libcouchbase_error_t libcouchbase_mget_by_key(libcouchbase_t instance,
libcouchbase_server_send_packets(server);
}

return LIBCOUCHBASE_SUCCESS;
return libcouchbase_synchandler_return(instance, LIBCOUCHBASE_SUCCESS);
}

static libcouchbase_error_t libcouchbase_single_get(libcouchbase_t instance,
Expand Down Expand Up @@ -179,5 +179,5 @@ static libcouchbase_error_t libcouchbase_single_get(libcouchbase_t instance,
libcouchbase_server_end_packet(server);
libcouchbase_server_send_packets(server);

return LIBCOUCHBASE_SUCCESS;
return libcouchbase_synchandler_return(instance, LIBCOUCHBASE_SUCCESS);
}
1 change: 1 addition & 0 deletions src/instance.c
Expand Up @@ -80,6 +80,7 @@ libcouchbase_t libcouchbase_create(const char *host,
return NULL;
}
libcouchbase_initialize_packet_handlers(ret);
libcouchbase_behavior_set_syncmode(ret, LIBCOUCHBASE_ASYNCHRONOUS);

ret->host = strdup(host);
if ((p = strchr(ret->host, ':')) == NULL) {
Expand Down
5 changes: 5 additions & 0 deletions src/internal.h
Expand Up @@ -121,6 +121,9 @@ extern "C" {

struct libcouchbase_io_opt_st *io;

/* The current synchronous mode */
libcouchbase_syncmode_t syncmode;

evutil_socket_t sock;
struct addrinfo *ai;
struct addrinfo *curr_ai;
Expand Down Expand Up @@ -210,6 +213,8 @@ extern "C" {
libcouchbase_t instance;
};

libcouchbase_error_t libcouchbase_synchandler_return(libcouchbase_t instance, libcouchbase_error_t retcode);

libcouchbase_error_t libcouchbase_error_handler(libcouchbase_t instance,
libcouchbase_error_t error,
const char *errinfo);
Expand Down
4 changes: 2 additions & 2 deletions src/remove.c
Expand Up @@ -47,7 +47,7 @@ libcouchbase_error_t libcouchbase_remove_by_key(libcouchbase_t instance,

/* we need a vbucket config before we can start removing the item.. */
if (instance->vbucket_config == NULL) {
return LIBCOUCHBASE_ETMPFAIL;
return libcouchbase_synchandler_return(instance, LIBCOUCHBASE_ETMPFAIL);
}

if (nhashkey == 0) {
Expand All @@ -74,5 +74,5 @@ libcouchbase_error_t libcouchbase_remove_by_key(libcouchbase_t instance,
libcouchbase_server_end_packet(server);
libcouchbase_server_send_packets(server);

return LIBCOUCHBASE_SUCCESS;
return libcouchbase_synchandler_return(instance, LIBCOUCHBASE_SUCCESS);
}
4 changes: 2 additions & 2 deletions src/stats.c
Expand Up @@ -34,7 +34,7 @@ libcouchbase_error_t libcouchbase_server_stats(libcouchbase_t instance,

/* we need a vbucket config before we can start getting data.. */
if (instance->vbucket_config == NULL) {
return LIBCOUCHBASE_ETMPFAIL;
return libcouchbase_synchandler_return(instance, LIBCOUCHBASE_ETMPFAIL);
}

memset(&req, 0, sizeof(req));
Expand All @@ -53,5 +53,5 @@ libcouchbase_error_t libcouchbase_server_stats(libcouchbase_t instance,
libcouchbase_server_end_packet(server);
libcouchbase_server_send_packets(server);
}
return LIBCOUCHBASE_SUCCESS;
return libcouchbase_synchandler_return(instance, LIBCOUCHBASE_SUCCESS);
}
9 changes: 5 additions & 4 deletions src/store.c
Expand Up @@ -56,7 +56,7 @@ libcouchbase_error_t libcouchbase_store_by_key(libcouchbase_t instance,

/* we need a vbucket config before we can start getting data.. */
if (instance->vbucket_config == NULL) {
return LIBCOUCHBASE_ETMPFAIL;
return libcouchbase_synchandler_return(instance, LIBCOUCHBASE_ETMPFAIL);
}

if (nhashkey == 0) {
Expand Down Expand Up @@ -100,8 +100,9 @@ libcouchbase_error_t libcouchbase_store_by_key(libcouchbase_t instance,
break;
default:
/* We were given an unknown storage operation. */
return libcouchbase_error_handler(instance, LIBCOUCHBASE_EINVAL,
"Invalid value passed as storage operation");
return libcouchbase_synchandler_return(instance,
libcouchbase_error_handler(instance, LIBCOUCHBASE_EINVAL,
"Invalid value passed as storage operation"));
}

/* Make it known that this was a success. */
Expand All @@ -116,5 +117,5 @@ libcouchbase_error_t libcouchbase_store_by_key(libcouchbase_t instance,
libcouchbase_server_end_packet(server);
libcouchbase_server_send_packets(server);

return LIBCOUCHBASE_SUCCESS;
return libcouchbase_synchandler_return(instance, LIBCOUCHBASE_SUCCESS);
}
75 changes: 75 additions & 0 deletions src/synchandler.c
@@ -0,0 +1,75 @@
/* -*- Mode: C; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
/*
* Copyright 2012 Couchbase, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* 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.
*/
#include "internal.h"

struct user_cookie {
void *cookie;
libcouchbase_error_callback error;
libcouchbase_error_t retcode;
};


static void error_callback(libcouchbase_t instance,
libcouchbase_error_t error,
const char *errinfo)
{
struct user_cookie *cookie = (void*)instance->cookie;
if (error == LIBCOUCHBASE_SUCCESS) {
return ;
}

/* Restore the users environment */
instance->cookie = cookie->cookie;
instance->callbacks.error = cookie->error;

/* Call the user's callback */
cookie->error(instance, error, errinfo);

/* Restore the wrapping environment */
cookie->error = instance->callbacks.error; /* User might have changed this */
instance->cookie = cookie;

/* Save the error code */
cookie->retcode = error;

/* Ok, stop the event loop */
instance->io->stop_event_loop(instance->io);
}

libcouchbase_error_t libcouchbase_synchandler_return(libcouchbase_t instance, libcouchbase_error_t retcode)
{
struct user_cookie cookie;

if (instance->syncmode == LIBCOUCHBASE_ASYNCHRONOUS ||
retcode != LIBCOUCHBASE_SUCCESS) {
return retcode;
}

cookie.retcode = LIBCOUCHBASE_SUCCESS;

/* Save the users environment */
cookie.error = instance->callbacks.error;
cookie.cookie = (void*)instance->cookie;
instance->cookie = &cookie;

libcouchbase_wait(instance);
/* Restore the environment */
instance->callbacks.error = cookie.error;
instance->cookie = cookie.cookie;

return cookie.retcode;
}
4 changes: 2 additions & 2 deletions src/touch.c
Expand Up @@ -53,7 +53,7 @@ libcouchbase_error_t libcouchbase_mtouch_by_key(libcouchbase_t instance,

/* we need a vbucket config before we can start getting data.. */
if (instance->vbucket_config == NULL) {
return LIBCOUCHBASE_ETMPFAIL;
return libcouchbase_synchandler_return(instance, LIBCOUCHBASE_ETMPFAIL);
}

if (nhashkey != 0) {
Expand Down Expand Up @@ -87,5 +87,5 @@ libcouchbase_error_t libcouchbase_mtouch_by_key(libcouchbase_t instance,

libcouchbase_server_send_packets(server);

return LIBCOUCHBASE_SUCCESS;
return libcouchbase_synchandler_return(instance, LIBCOUCHBASE_SUCCESS);
}

0 comments on commit 64e519c

Please sign in to comment.