summaryrefslogtreecommitdiff
path: root/examples/c/ex_rep/common
diff options
context:
space:
mode:
Diffstat (limited to 'examples/c/ex_rep/common')
-rw-r--r--examples/c/ex_rep/common/rep_common.c76
-rw-r--r--examples/c/ex_rep/common/rep_common.h30
2 files changed, 103 insertions, 3 deletions
diff --git a/examples/c/ex_rep/common/rep_common.c b/examples/c/ex_rep/common/rep_common.c
index a091adda..d7d2585a 100644
--- a/examples/c/ex_rep/common/rep_common.c
+++ b/examples/c/ex_rep/common/rep_common.c
@@ -1,7 +1,7 @@
/*-
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 2006, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2015 Oracle and/or its affiliates. All rights reserved.
*
* $Id$
*/
@@ -19,6 +19,18 @@
#define DATABASE "quote.db"
#define SLEEPTIME 3
+/*
+ * Definition of thread-specific data key for PERM_FAILED structure
+ * stored in thread local storage.
+ */
+#ifdef _WIN32
+/* Windows style. */
+DWORD permfail_key;
+#else
+/* Posix style. */
+pthread_key_t permfail_key;
+#endif
+
static int print_stocks __P((DB *));
/*
@@ -346,15 +358,27 @@ doloop(dbenv, shared_data)
{
DB *dbp;
DBT key, data;
+ permfail_t *pfinfo;
char buf[BUFSIZE], *first, *price;
u_int32_t flags;
int ret;
dbp = NULL;
+ pfinfo = NULL;
ret = 0;
memset(&key, 0, sizeof(key));
memset(&data, 0, sizeof(data));
+ /* Allocate put/commit thread's PERM_FAILED structure. */
+ if (shared_data->is_repmgr) {
+ if ((pfinfo = malloc(sizeof(permfail_t))) == NULL)
+ goto err;
+ if ((ret = thread_setspecific(permfail_key, pfinfo)) != 0)
+ goto err;
+ pfinfo->thread_name = "PutCommit";
+ pfinfo->flag = 0;
+ }
+
for (;;) {
printf("QUOTESERVER%s> ",
shared_data->is_master ? "" : " (read-only)");
@@ -431,6 +455,16 @@ doloop(dbenv, shared_data)
dbenv->err(dbenv, ret, "DB->open");
goto err;
}
+ /* Check this thread's PERM_FAILED indicator. */
+ if (shared_data->is_repmgr) {
+ pfinfo = (permfail_t *)thread_getspecific(
+ permfail_key);
+ if (pfinfo->flag)
+ printf(
+ "%s Thread: dbopen not durable.\n",
+ pfinfo->thread_name);
+ pfinfo->flag = 0;
+ }
}
if (first == NULL) {
@@ -470,11 +504,23 @@ doloop(dbenv, shared_data)
dbp->err(dbp, ret, "DB->put");
goto err;
}
+ /* Check this thread's PERM_FAILED indicator. */
+ if (shared_data->is_repmgr) {
+ pfinfo = (permfail_t *)thread_getspecific(
+ permfail_key);
+ if (pfinfo->flag)
+ printf(
+ "%s Thread: put %s %s not durable.\n",
+ pfinfo->thread_name, first, price);
+ pfinfo->flag = 0;
+ }
}
}
err: if (dbp != NULL)
(void)dbp->close(dbp, DB_NOSYNC);
+ if (pfinfo != NULL)
+ free(pfinfo);
return (ret);
}
@@ -575,12 +621,24 @@ checkpoint_thread(args)
{
DB_ENV *dbenv;
SHARED_DATA *shared;
+ permfail_t *pfinfo;
supthr_args *ca;
int i, ret;
ca = (supthr_args *)args;
dbenv = ca->dbenv;
shared = ca->shared;
+ pfinfo = NULL;
+
+ /* Allocate checkpoint thread's PERM_FAILED structure. */
+ if (shared->is_repmgr) {
+ if ((pfinfo = malloc(sizeof(permfail_t))) == NULL)
+ return ((void *)EXIT_FAILURE);
+ if ((ret = thread_setspecific(permfail_key, pfinfo)) != 0)
+ return ((void *)EXIT_FAILURE);
+ pfinfo->thread_name = "Checkpoint";
+ pfinfo->flag = 0;
+ }
for (;;) {
/*
@@ -590,16 +648,30 @@ checkpoint_thread(args)
*/
for (i = 0; i < 60; i++) {
sleep(1);
- if (shared->app_finished == 1)
+ if (shared->app_finished == 1) {
+ if (pfinfo != NULL)
+ free(pfinfo);
return ((void *)EXIT_SUCCESS);
+ }
}
/* Perform a checkpoint. */
if ((ret = dbenv->txn_checkpoint(dbenv, 0, 0, 0)) != 0) {
dbenv->err(dbenv, ret,
"Could not perform checkpoint.\n");
+ if (pfinfo != NULL)
+ free(pfinfo);
return ((void *)EXIT_FAILURE);
}
+ /* Check this thread's PERM_FAILED indicator. */
+ if (shared->is_repmgr) {
+ pfinfo = (permfail_t *)thread_getspecific(
+ permfail_key);
+ if (pfinfo->flag)
+ printf("%s Thread: checkpoint not durable.\n",
+ pfinfo->thread_name);
+ pfinfo->flag = 0;
+ }
}
}
diff --git a/examples/c/ex_rep/common/rep_common.h b/examples/c/ex_rep/common/rep_common.h
index edf3b67d..8f7d1348 100644
--- a/examples/c/ex_rep/common/rep_common.h
+++ b/examples/c/ex_rep/common/rep_common.h
@@ -1,7 +1,7 @@
/*-
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 2006, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2015 Oracle and/or its affiliates. All rights reserved.
*
* $Id$
*/
@@ -33,6 +33,7 @@ typedef struct {
int is_master;
int app_finished;
int in_client_sync;
+ int is_repmgr;
} SHARED_DATA;
/* Arguments for support threads. */
@@ -41,6 +42,15 @@ typedef struct {
SHARED_DATA *shared;
} supthr_args;
+/*
+ * Per-thread Replication Manager structure to associate a PERM_FAILED event
+ * with its originating transaction.
+ */
+typedef struct {
+ char *thread_name;
+ int flag;
+} permfail_t;
+
/* Portability macros for basic threading & timing */
#ifdef _WIN32
#define WIN32_LEAN_AND_MEAN
@@ -59,6 +69,16 @@ typedef HANDLE thread_t;
((WaitForSingleObject((thr), INFINITE) == WAIT_OBJECT_0) && \
GetExitCodeThread((thr), (LPDWORD)(statusp)) ? 0 : -1)
+/* Thread-specific data key for PERM_FAILED structure for Windows. */
+extern DWORD permfail_key;
+/* Thread local storage routine definitions for Windows. */
+#define thread_key_create(keyp) ((*keyp = TlsAlloc()) == \
+ TLS_OUT_OF_INDEXES ? (int)GetLastError() : 0)
+#define thread_key_delete(key) (TlsFree(key) ? 0 : (int)GetLastError())
+#define thread_setspecific(key, value) (TlsSetValue(key, value) ? 0 : \
+ (int)GetLastError())
+#define thread_getspecific(key) TlsGetValue(key)
+
#else /* !_WIN32 */
#include <sys/time.h>
#include <pthread.h>
@@ -68,6 +88,14 @@ typedef pthread_t thread_t;
pthread_create((thrp), (attr), (func), (arg))
#define thread_join(thr, statusp) pthread_join((thr), (statusp))
+/* Thread-specific data key for PERM_FAILED structure for Posix. */
+extern pthread_key_t permfail_key;
+/* Thread local storage routine definitions for Posix. */
+#define thread_key_create(keyp) pthread_key_create(keyp, NULL)
+#define thread_key_delete(key) pthread_key_delete(key)
+#define thread_setspecific(key, value) pthread_setspecific(key, value)
+#define thread_getspecific(key) pthread_getspecific(key)
+
#endif
void *checkpoint_thread __P((void *));