diff options
Diffstat (limited to 'libglusterfs')
-rw-r--r-- | libglusterfs/src/iobuf.c | 139 | ||||
-rw-r--r-- | libglusterfs/src/iobuf.h | 13 |
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_ */ |