Browse Source

tdb2: Internal error helpers.

I use the "high pointers hold error numbers" trick, and also make
tdb_logerr return the error code, which enables the common case of
"return tdb_logerr(...)".
Rusty Russell 15 years ago
parent
commit
f6d1f564b9
3 changed files with 23 additions and 11 deletions
  1. 14 4
      ccan/tdb2/private.h
  2. 7 6
      ccan/tdb2/tdb.c
  3. 2 1
      ccan/tdb2/tdb2.h

+ 14 - 4
ccan/tdb2/private.h

@@ -74,6 +74,16 @@ typedef uint64_t tdb_off_t;
 #define TDB_RECOVERY_INVALID_MAGIC (0x0ULL)
 
 #define TDB_OFF_ERR ((tdb_off_t)-1)
+#define TDB_OFF_IS_ERR(off) unlikely(off >= (tdb_off_t)TDB_ERR_LAST)
+
+/* Packing errors into pointers and v.v. */
+#define TDB_PTR_IS_ERR(ptr) \
+	unlikely((void *)(ptr) >= (void *)(long)TDB_ERR_LAST)
+#define TDB_PTR_ERR(p) ((enum TDB_ERROR)(long)(p))
+#define TDB_ERR_PTR(err) ((void *)(long)(err))
+
+/* Common case of returning true, false or -ve error. */
+typedef int tdb_bool_err;
 
 /* Prevent others from opening the file. */
 #define TDB_OPEN_LOCK 0
@@ -551,10 +561,10 @@ int tdb_transaction_recover(struct tdb_context *tdb);
 bool tdb_needs_recovery(struct tdb_context *tdb);
 
 /* tdb.c: */
-void COLD tdb_logerr(struct tdb_context *tdb,
-		     enum TDB_ERROR ecode,
-		     enum tdb_log_level level,
-		     const char *fmt, ...);
+enum TDB_ERROR COLD tdb_logerr(struct tdb_context *tdb,
+			       enum TDB_ERROR ecode,
+			       enum tdb_log_level level,
+			       const char *fmt, ...);
 
 #ifdef TDB_TRACE
 void tdb_trace(struct tdb_context *tdb, const char *op);

+ 7 - 6
ccan/tdb2/tdb.c

@@ -706,10 +706,10 @@ const char *tdb_errorstr(const struct tdb_context *tdb)
 	return "Invalid error code";
 }
 
-void COLD tdb_logerr(struct tdb_context *tdb,
-		     enum TDB_ERROR ecode,
-		     enum tdb_log_level level,
-		     const char *fmt, ...)
+enum TDB_ERROR COLD tdb_logerr(struct tdb_context *tdb,
+			       enum TDB_ERROR ecode,
+			       enum tdb_log_level level,
+			       const char *fmt, ...)
 {
 	char *message;
 	va_list ap;
@@ -720,7 +720,7 @@ void COLD tdb_logerr(struct tdb_context *tdb,
 	tdb->ecode = ecode;
 
 	if (!tdb->logfn)
-		return;
+		return ecode;
 
 	/* FIXME: Doesn't assume asprintf. */
 	va_start(ap, fmt);
@@ -732,7 +732,7 @@ void COLD tdb_logerr(struct tdb_context *tdb,
 		tdb->logfn(tdb, TDB_LOG_ERROR, tdb->log_private,
 			   "out of memory formatting message:");
 		tdb->logfn(tdb, level, tdb->log_private, fmt);
-		return;
+		return ecode;
 	}
 	va_start(ap, fmt);
 	len = vsprintf(message, fmt, ap);
@@ -740,4 +740,5 @@ void COLD tdb_logerr(struct tdb_context *tdb,
 	tdb->logfn(tdb, level, tdb->log_private, message);
 	free(message);
 	errno = saved_errno;
+	return ecode;
 }

+ 2 - 1
ccan/tdb2/tdb2.h

@@ -111,7 +111,8 @@ enum TDB_ERROR {
 	TDB_ERR_EXISTS	= -5,	/* The key already exists. */
 	TDB_ERR_NOEXIST	= -6,	/* The key does not exist. */
 	TDB_ERR_EINVAL	= -7,	/* You're using it wrong. */
-	TDB_ERR_RDONLY	= -8	/* The database is read-only. */
+	TDB_ERR_RDONLY	= -8,	/* The database is read-only. */
+	TDB_ERR_LAST = TDB_ERR_RDONLY
 };
 
 /**