Commit 7b083d3cd370e66288ae017ac02020b041f33027

Edward Thomson 2019-03-02T18:14:36

Merge pull request #5005 from libgit2/ethomson/odb_backend_allocations odb: provide a free function for custom backends

diff --git a/include/git2/sys/odb_backend.h b/include/git2/sys/odb_backend.h
index bc2af12..6614dcf 100644
--- a/include/git2/sys/odb_backend.h
+++ b/include/git2/sys/odb_backend.h
@@ -30,8 +30,8 @@ struct git_odb_backend {
 
 	/* read and read_prefix each return to libgit2 a buffer which
 	 * will be freed later. The buffer should be allocated using
-	 * the function git_odb_backend_malloc to ensure that it can
-	 * be safely freed later. */
+	 * the function git_odb_backend_data_alloc to ensure that libgit2
+	 * can safely free it later. */
 	int GIT_CALLBACK(read)(
 		void **, size_t *, git_object_t *, git_odb_backend *, const git_oid *);
 
@@ -117,8 +117,52 @@ GIT_EXTERN(int) git_odb_init_backend(
 	git_odb_backend *backend,
 	unsigned int version);
 
+/**
+ * Allocate data for an ODB object.  Custom ODB backends may use this
+ * to provide data back to the ODB from their read function.  This
+ * memory should not be freed once it is returned to libgit2.  If a
+ * custom ODB uses this function but encounters an error and does not
+ * return this data to libgit2, then they should use the corresponding
+ * git_odb_backend_data_free function.
+ *
+ * @param backend the ODB backend that is allocating this memory
+ * @param len the number of bytes to allocate
+ * @return the allocated buffer on success or NULL if out of memory
+ */
+GIT_EXTERN(void *) git_odb_backend_data_alloc(git_odb_backend *backend, size_t len);
+
+/**
+ * Frees custom allocated ODB data.  This should only be called when
+ * memory allocated using git_odb_backend_data_alloc is not returned
+ * to libgit2 because the backend encountered an error in the read
+ * function after allocation and did not return this data to libgit2.
+ *
+ * @param backend the ODB backend that is freeing this memory
+ * @param data the buffer to free
+ */
+GIT_EXTERN(void) git_odb_backend_data_free(git_odb_backend *backend, void *data);
+
+
+/*
+ * Users can avoid deprecated functions by defining `GIT_DEPRECATE_HARD`.
+ */
+#ifndef GIT_DEPRECATE_HARD
+
+/**
+ * Allocate memory for an ODB object from a custom backend.  This is
+ * an alias of `git_odb_backend_data_alloc` and is preserved for
+ * backward compatibility.
+ *
+ * This function is deprecated, but there is no plan to remove this
+ * function at this time.
+ *
+ * @deprecated git_odb_backend_data_alloc
+ * @see git_odb_backend_data_alloc
+ */
 GIT_EXTERN(void *) git_odb_backend_malloc(git_odb_backend *backend, size_t len);
 
+#endif
+
 GIT_END_DECL
 
 #endif
diff --git a/src/odb.c b/src/odb.c
index b2442a8..1c923c5 100644
--- a/src/odb.c
+++ b/src/odb.c
@@ -1497,12 +1497,23 @@ int git_odb_write_pack(struct git_odb_writepack **out, git_odb *db, git_indexer_
 	return error;
 }
 
-void *git_odb_backend_malloc(git_odb_backend *backend, size_t len)
+void *git_odb_backend_data_alloc(git_odb_backend *backend, size_t len)
 {
 	GIT_UNUSED(backend);
 	return git__malloc(len);
 }
 
+void *git_odb_backend_malloc(git_odb_backend *backend, size_t len)
+{
+	return git_odb_backend_data_alloc(backend, len);
+}
+
+void git_odb_backend_data_free(git_odb_backend *backend, void *data)
+{
+	GIT_UNUSED(backend);
+	git__free(data);
+}
+
 int git_odb_refresh(struct git_odb *db)
 {
 	size_t i;