summaryrefslogtreecommitdiffstats
path: root/libglusterfs
diff options
context:
space:
mode:
Diffstat (limited to 'libglusterfs')
-rw-r--r--libglusterfs/src/iobuf.c139
-rw-r--r--libglusterfs/src/iobuf.h13
2 files changed, 152 insertions, 0 deletions
diff --git a/libglusterfs/src/iobuf.c b/libglusterfs/src/iobuf.c
index 5d1f37c0391..b11438b38d9 100644
--- a/libglusterfs/src/iobuf.c
+++ b/libglusterfs/src/iobuf.c
@@ -392,3 +392,142 @@ iobuf_ref (struct iobuf *iobuf)
return iobuf;
}
+
+
+struct iobref *
+iobref_new ()
+{
+ struct iobref *iobref = NULL;
+
+ iobref = CALLOC (sizeof (*iobref), 1);
+ if (!iobref)
+ return NULL;
+
+ LOCK_INIT (&iobref->lock);
+
+ iobref->ref++;
+
+ return iobref;
+}
+
+
+struct iobref *
+iobref_ref (struct iobref *iobref)
+{
+ if (!iobref)
+ return NULL;
+
+ LOCK (&iobref->lock);
+ {
+ iobref->ref++;
+ }
+ UNLOCK (&iobref->lock);
+
+ return iobref;
+}
+
+
+void
+iobref_destroy (struct iobref *iobref)
+{
+ int i = 0;
+ struct iobuf *iobuf = NULL;
+
+ if (!iobref)
+ return;
+
+ for (i = 0; i < 8; i++) {
+ iobuf = iobref->iobrefs[i];
+
+ iobref->iobrefs[i] = NULL;
+ if (iobuf)
+ iobuf_unref (iobuf);
+ }
+
+ FREE (iobref);
+}
+
+
+void
+iobref_unref (struct iobref *iobref)
+{
+ int ref = 0;
+
+ if (!iobref)
+ return;
+
+ LOCK (&iobref->lock);
+ {
+ ref = (--iobref->ref);
+ }
+ UNLOCK (&iobref->lock);
+
+ if (!ref)
+ iobref_destroy (iobref);
+}
+
+
+int
+__iobref_add (struct iobref *iobref, struct iobuf *iobuf)
+{
+ int i = 0;
+ int ret = -ENOMEM;
+
+ for (i = 0; i < 8; i++) {
+ if (iobref->iobrefs[i] == NULL) {
+ iobref->iobrefs[i] = iobuf_ref (iobuf);
+ ret = 0;
+ break;
+ }
+ }
+
+ return ret;
+}
+
+
+int
+iobref_add (struct iobref *iobref, struct iobuf *iobuf)
+{
+ int ret = 0;
+
+ if (!iobref)
+ return -EINVAL;
+
+ if (!iobuf)
+ return -EINVAL;
+
+ LOCK (&iobref->lock);
+ {
+ ret = __iobref_add (iobref, iobuf);
+ }
+ UNLOCK (&iobref->lock);
+
+ return ret;
+}
+
+
+int
+iobref_merge (struct iobref *to, struct iobref *from)
+{
+ int i = 0;
+ int ret = 0;
+ struct iobuf *iobuf = NULL;
+
+ LOCK (&from->lock);
+ {
+ for (i = 0; i < 8; i++) {
+ iobuf = from->iobrefs[i];
+
+ if (!iobuf)
+ break;
+
+ ret = iobref_add (to, iobuf);
+
+ if (ret < 0)
+ break;
+ }
+ }
+ UNLOCK (&from->lock);
+
+ return ret;
+}
diff --git a/libglusterfs/src/iobuf.h b/libglusterfs/src/iobuf.h
index 8a854db8f41..3d389b82fc9 100644
--- a/libglusterfs/src/iobuf.h
+++ b/libglusterfs/src/iobuf.h
@@ -94,4 +94,17 @@ struct iobuf_pool *iobuf_pool_new (size_t arena_size, size_t page_size);
struct iobuf *iobuf_get (struct iobuf_pool *iobuf_pool);
void iobuf_unref (struct iobuf *iobuf);
+
+struct iobref {
+ gf_lock_t lock;
+ int ref;
+ struct iobuf *iobrefs[8];
+};
+
+struct iobref *iobref_new ();
+struct iobref *iobref_ref (struct iobref *iobref);
+void iobref_unref (struct iobref *iobref);
+int iobref_add (struct iobref *iobref, struct iobuf *iobuf);
+int iobref_merge (struct iobref *to, struct iobref *from);
+
#endif /* !_IOBUF_H_ */