{"thread":{"id":"25654","subject":"[PATCH/RFC 0/8] Remove various dependencies from wrapper.o","startedAt":"2010-11-06T11:39:05Z","lastAt":"2010-11-07T18:23:41Z","messageCount":14,"participants":["Jonathan Nieder","René Scharfe"],"isPatch":true,"patchVersion":1,"patchTotal":8},"messages":[{"id":"155287","messageId":"20101106113905.GA27405@burratino","threadId":"25654","inReplyTo":null,"subject":"[PATCH/RFC 0/8] Remove various dependencies from wrapper.o","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-11-06T11:39:05Z","receivedAt":"2010-11-06T11:39:05Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Hi,\n\nRam noticed that using any function from strbuf.c results in a larger\nbinary that requires -lz to link, which is pretty far from ideal.\nThis patch series moves code around to make that no longer the case.\n\nVaguely inspired by [1].\n\nAfter applying these patches, you can write:\n\n\t#define SHA1_HEADER \"block-sha1/sha1.h\"\n\t#include \"cache.h\"\n\tint main(void)\n\t{\n\t\tvolatile char *p = xmalloc(5);\n\t\treturn 0;\n\t}\n\nand build it with\n\n\tcc -Wall -W test.c wrapper.o usage.o\n\n-- no libz needed, no sha1 library, no environment.c, small binary.\n\nOf course, making the linker happy tends to make the code clearer,\ntoo.\n\nPatch 1 moves xmmap to sha1_file.c, where release_pack_memory()\nis defined.  If xmmap were used by tiny programs, maybe it would\nmake sense to replace release_pack_memory() with a callback,\nbut this is simpler.\n\nPatch 2 moves odb_mkstemp and odb_pack_keep to environment.c,\nwere they have access to the cached value of $GIT_OBJECT_DIRECTORY.\n\nPatch 3 moves git_mkstemps_mode et al from path.c to wrapper.c,\nso xmkstemp_mode does not have to depend on path.c.\n\nPatch 4 moves some refname-related functions from strbuf.c to\nsha1_name.c.\n\nPatch 5 moves git_inflate et al to a new zlib.c, so wrapper.o does\nnot have to depend directly on libz.\n\nPatch 6 is a missing \"static\" keyword.  It probably doesn't belong\nin this series, but it fits okay.\n\nPatch 7 moves try_to_free_builtin to sha1_file.c and adds a\ndeclaration for it to git-compat-util.h.\n\nPatch 8 stops referring to try_to_free_builtin from wrapper.c,\ncompleting the project.\n\nThoughts?  Improvements?  Benchmarks?\n\n[1] http://thread.gmane.org/gmane.comp.version-control.git/137686/focus=137737\n\nJonathan Nieder (8):\n  wrapper: move xmmap() to sha1_file.c\n  wrapper: move odb_* to environment.c\n  path helpers: move git_mkstemp* to wrapper.c\n  strbuf: move strbuf_branchname to sha1_name.c\n  wrapper: give zlib wrappers their own translation unit\n  pack-objects: mark file-local variable static\n  wrapper: expose try_to_free_pack_memory()\n  Remove pack file handling dependency from wrapper.o\n\n Makefile                                  |    1 +\n builtin/pack-objects.c                    |    2 +-\n check-racy.c                              |    1 +\n contrib/convert-objects/convert-objects.c |    1 +\n daemon.c                                  |    1 +\n environment.c                             |   37 ++++++\n fast-import.c                             |    1 +\n git-compat-util.h                         |    2 +\n git.c                                     |    2 +\n http-backend.c                            |    1 +\n http-fetch.c                              |    1 +\n http-push.c                               |    1 +\n imap-send.c                               |    1 +\n path.c                                    |  113 ----------------\n remote-curl.c                             |    1 +\n sha1_file.c                               |   20 +++\n sha1_name.c                               |   16 +++\n strbuf.c                                  |   16 ---\n test-dump-cache-tree.c                    |    4 +-\n test-match-trees.c                        |    1 +\n upload-pack.c                             |    1 +\n wrapper.c                                 |  198 ++++++++++++++--------------\n zlib.c                                    |   61 +++++++++\n 23 files changed, 253 insertions(+), 230 deletions(-)\n create mode 100644 zlib.c\n\n-- \n1.7.2.3.557.gab647.dirty\n"},{"id":"155288","messageId":"20101106114411.GA27641@burratino","threadId":"25654","inReplyTo":"20101106113905.GA27405@burratino","subject":"[PATCH 1/8] wrapper: move xmmap() to sha1_file.c","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-11-06T11:44:11Z","receivedAt":"2010-11-06T11:44:11Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"wrapper.o depends on sha1_file.o for a number of reasons.  One is\nrelease_pack_memory().\n\nxmmap function calls mmap, discarding unused pack windows when\nnecessary to relieve memory pressure.  Simple git programs using\nwrapper.o as a friendly libc do not need this functionality.\nSo move xmmap to sha1_file.o, where release_pack_memory() is.\n\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\n---\n sha1_file.c |   15 +++++++++++++++\n wrapper.c   |   15 ---------------\n 2 files changed, 15 insertions(+), 15 deletions(-)\n\ndiff --git a/sha1_file.c b/sha1_file.c\nindex 0cd9435..8e299ae 100644\n--- a/sha1_file.c\n+++ b/sha1_file.c\n@@ -576,6 +576,21 @@ void release_pack_memory(size_t need, int fd)\n \t\t; /* nothing */\n }\n \n+void *xmmap(void *start, size_t length,\n+\tint prot, int flags, int fd, off_t offset)\n+{\n+\tvoid *ret = mmap(start, length, prot, flags, fd, offset);\n+\tif (ret == MAP_FAILED) {\n+\t\tif (!length)\n+\t\t\treturn NULL;\n+\t\trelease_pack_memory(length, fd);\n+\t\tret = mmap(start, length, prot, flags, fd, offset);\n+\t\tif (ret == MAP_FAILED)\n+\t\t\tdie_errno(\"Out of memory? mmap failed\");\n+\t}\n+\treturn ret;\n+}\n+\n void close_pack_windows(struct packed_git *p)\n {\n \twhile (p->windows) {\ndiff --git a/wrapper.c b/wrapper.c\nindex fd8ead3..3195ef3 100644\n--- a/wrapper.c\n+++ b/wrapper.c\n@@ -108,21 +108,6 @@ void *xcalloc(size_t nmemb, size_t size)\n \treturn ret;\n }\n \n-void *xmmap(void *start, size_t length,\n-\tint prot, int flags, int fd, off_t offset)\n-{\n-\tvoid *ret = mmap(start, length, prot, flags, fd, offset);\n-\tif (ret == MAP_FAILED) {\n-\t\tif (!length)\n-\t\t\treturn NULL;\n-\t\trelease_pack_memory(length, fd);\n-\t\tret = mmap(start, length, prot, flags, fd, offset);\n-\t\tif (ret == MAP_FAILED)\n-\t\t\tdie_errno(\"Out of memory? mmap failed\");\n-\t}\n-\treturn ret;\n-}\n-\n /*\n  * xread() is the same a read(), but it automatically restarts read()\n  * operations with a recoverable error (EAGAIN and EINTR). xread()\n-- \n1.7.2.3.557.gab647.dirty\n"},{"id":"155289","messageId":"20101106114538.GB27641@burratino","threadId":"25654","inReplyTo":"20101106113905.GA27405@burratino","subject":"[PATCH 2/8] wrapper: move odb_* to environment.c","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-11-06T11:45:38Z","receivedAt":"2010-11-06T11:45:38Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"The odb_mkstemp and odb_pack_keep functions open files under the\n$GIT_OBJECT_DIRECTORY directory.  This requires access to the git\nconfiguration which very simple programs do not need.\n\nMove these functions to environment.o, closer to their dependencies.\nThis should make it easier for programs to link to wrapper.o without\nlinking to environment.o.\n\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\n---\n environment.c     |   37 +++++++++++++++++++++++++++++++++++++\n git-compat-util.h |    1 +\n wrapper.c         |   37 -------------------------------------\n 3 files changed, 38 insertions(+), 37 deletions(-)\n\ndiff --git a/environment.c b/environment.c\nindex de5581f..95777f4 100644\n--- a/environment.c\n+++ b/environment.c\n@@ -171,6 +171,43 @@ char *get_object_directory(void)\n \treturn git_object_dir;\n }\n \n+int odb_mkstemp(char *template, size_t limit, const char *pattern)\n+{\n+\tint fd;\n+\t/*\n+\t * we let the umask do its job, don't try to be more\n+\t * restrictive except to remove write permission.\n+\t */\n+\tint mode = 0444;\n+\tsnprintf(template, limit, \"%s/%s\",\n+\t\t get_object_directory(), pattern);\n+\tfd = git_mkstemp_mode(template, mode);\n+\tif (0 <= fd)\n+\t\treturn fd;\n+\n+\t/* slow path */\n+\t/* some mkstemp implementations erase template on failure */\n+\tsnprintf(template, limit, \"%s/%s\",\n+\t\t get_object_directory(), pattern);\n+\tsafe_create_leading_directories(template);\n+\treturn xmkstemp_mode(template, mode);\n+}\n+\n+int odb_pack_keep(char *name, size_t namesz, unsigned char *sha1)\n+{\n+\tint fd;\n+\n+\tsnprintf(name, namesz, \"%s/pack/pack-%s.keep\",\n+\t\t get_object_directory(), sha1_to_hex(sha1));\n+\tfd = open(name, O_RDWR|O_CREAT|O_EXCL, 0600);\n+\tif (0 <= fd)\n+\t\treturn fd;\n+\n+\t/* slow path */\n+\tsafe_create_leading_directories(name);\n+\treturn open(name, O_RDWR|O_CREAT|O_EXCL, 0600);\n+}\n+\n char *get_index_file(void)\n {\n \tif (!git_index_file)\ndiff --git a/git-compat-util.h b/git-compat-util.h\nindex 2af8d3e..029162e 100644\n--- a/git-compat-util.h\n+++ b/git-compat-util.h\n@@ -404,6 +404,7 @@ extern ssize_t xwrite(int fd, const void *buf, size_t len);\n extern int xdup(int fd);\n extern FILE *xfdopen(int fd, const char *mode);\n extern int xmkstemp(char *template);\n+extern int xmkstemp_mode(char *template, int mode);\n extern int odb_mkstemp(char *template, size_t limit, const char *pattern);\n extern int odb_pack_keep(char *name, size_t namesz, unsigned char *sha1);\n \ndiff --git a/wrapper.c b/wrapper.c\nindex 3195ef3..e67b70a 100644\n--- a/wrapper.c\n+++ b/wrapper.c\n@@ -274,43 +274,6 @@ int git_inflate(z_streamp strm, int flush)\n \treturn ret;\n }\n \n-int odb_mkstemp(char *template, size_t limit, const char *pattern)\n-{\n-\tint fd;\n-\t/*\n-\t * we let the umask do its job, don't try to be more\n-\t * restrictive except to remove write permission.\n-\t */\n-\tint mode = 0444;\n-\tsnprintf(template, limit, \"%s/%s\",\n-\t\t get_object_directory(), pattern);\n-\tfd = git_mkstemp_mode(template, mode);\n-\tif (0 <= fd)\n-\t\treturn fd;\n-\n-\t/* slow path */\n-\t/* some mkstemp implementations erase template on failure */\n-\tsnprintf(template, limit, \"%s/%s\",\n-\t\t get_object_directory(), pattern);\n-\tsafe_create_leading_directories(template);\n-\treturn xmkstemp_mode(template, mode);\n-}\n-\n-int odb_pack_keep(char *name, size_t namesz, unsigned char *sha1)\n-{\n-\tint fd;\n-\n-\tsnprintf(name, namesz, \"%s/pack/pack-%s.keep\",\n-\t\t get_object_directory(), sha1_to_hex(sha1));\n-\tfd = open(name, O_RDWR|O_CREAT|O_EXCL, 0600);\n-\tif (0 <= fd)\n-\t\treturn fd;\n-\n-\t/* slow path */\n-\tsafe_create_leading_directories(name);\n-\treturn open(name, O_RDWR|O_CREAT|O_EXCL, 0600);\n-}\n-\n static int warn_if_unremovable(const char *op, const char *file, int rc)\n {\n \tif (rc < 0) {\n-- \n1.7.2.3.557.gab647.dirty\n"},{"id":"155290","messageId":"20101106114631.GC27641@burratino","threadId":"25654","inReplyTo":"20101106113905.GA27405@burratino","subject":"[PATCH 3/8] path helpers: move git_mkstemp* to wrapper.c","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-11-06T11:46:31Z","receivedAt":"2010-11-06T11:46:31Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"git_mkstemp_mode and related functions do not require access to\nspecialized git machinery, unlike some other functions from\npath.c (like set_shared_perm()).  Move them to wrapper.c where\nthe wrapper xmkstemp_mode is defined.\n\nThis eliminates a dependency of wrapper.o on environment.o via\npath.o.  With typical linkers (e.g., gcc), that dependency makes\nprograms that use functions from wrapper.o and not environment.o\nor path.o larger than they need to be.\n\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\n---\n path.c    |  113 -------------------------------------------------------------\n wrapper.c |  113 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n 2 files changed, 113 insertions(+), 113 deletions(-)\n\ndiff --git a/path.c b/path.c\nindex a2c9d1e..8951333 100644\n--- a/path.c\n+++ b/path.c\n@@ -161,119 +161,6 @@ char *git_path_submodule(const char *path, const char *fmt, ...)\n \treturn cleanup_path(pathname);\n }\n \n-/* git_mkstemp() - create tmp file honoring TMPDIR variable */\n-int git_mkstemp(char *path, size_t len, const char *template)\n-{\n-\tconst char *tmp;\n-\tsize_t n;\n-\n-\ttmp = getenv(\"TMPDIR\");\n-\tif (!tmp)\n-\t\ttmp = \"/tmp\";\n-\tn = snprintf(path, len, \"%s/%s\", tmp, template);\n-\tif (len <= n) {\n-\t\terrno = ENAMETOOLONG;\n-\t\treturn -1;\n-\t}\n-\treturn mkstemp(path);\n-}\n-\n-/* git_mkstemps() - create tmp file with suffix honoring TMPDIR variable. */\n-int git_mkstemps(char *path, size_t len, const char *template, int suffix_len)\n-{\n-\tconst char *tmp;\n-\tsize_t n;\n-\n-\ttmp = getenv(\"TMPDIR\");\n-\tif (!tmp)\n-\t\ttmp = \"/tmp\";\n-\tn = snprintf(path, len, \"%s/%s\", tmp, template);\n-\tif (len <= n) {\n-\t\terrno = ENAMETOOLONG;\n-\t\treturn -1;\n-\t}\n-\treturn mkstemps(path, suffix_len);\n-}\n-\n-/* Adapted from libiberty's mkstemp.c. */\n-\n-#undef TMP_MAX\n-#define TMP_MAX 16384\n-\n-int git_mkstemps_mode(char *pattern, int suffix_len, int mode)\n-{\n-\tstatic const char letters[] =\n-\t\t\"abcdefghijklmnopqrstuvwxyz\"\n-\t\t\"ABCDEFGHIJKLMNOPQRSTUVWXYZ\"\n-\t\t\"0123456789\";\n-\tstatic const int num_letters = 62;\n-\tuint64_t value;\n-\tstruct timeval tv;\n-\tchar *template;\n-\tsize_t len;\n-\tint fd, count;\n-\n-\tlen = strlen(pattern);\n-\n-\tif (len < 6 + suffix_len) {\n-\t\terrno = EINVAL;\n-\t\treturn -1;\n-\t}\n-\n-\tif (strncmp(&pattern[len - 6 - suffix_len], \"XXXXXX\", 6)) {\n-\t\terrno = EINVAL;\n-\t\treturn -1;\n-\t}\n-\n-\t/*\n-\t * Replace pattern's XXXXXX characters with randomness.\n-\t * Try TMP_MAX different filenames.\n-\t */\n-\tgettimeofday(&tv, NULL);\n-\tvalue = ((size_t)(tv.tv_usec << 16)) ^ tv.tv_sec ^ getpid();\n-\ttemplate = &pattern[len - 6 - suffix_len];\n-\tfor (count = 0; count < TMP_MAX; ++count) {\n-\t\tuint64_t v = value;\n-\t\t/* Fill in the random bits. */\n-\t\ttemplate[0] = letters[v % num_letters]; v /= num_letters;\n-\t\ttemplate[1] = letters[v % num_letters]; v /= num_letters;\n-\t\ttemplate[2] = letters[v % num_letters]; v /= num_letters;\n-\t\ttemplate[3] = letters[v % num_letters]; v /= num_letters;\n-\t\ttemplate[4] = letters[v % num_letters]; v /= num_letters;\n-\t\ttemplate[5] = letters[v % num_letters]; v /= num_letters;\n-\n-\t\tfd = open(pattern, O_CREAT | O_EXCL | O_RDWR, mode);\n-\t\tif (fd > 0)\n-\t\t\treturn fd;\n-\t\t/*\n-\t\t * Fatal error (EPERM, ENOSPC etc).\n-\t\t * It doesn't make sense to loop.\n-\t\t */\n-\t\tif (errno != EEXIST)\n-\t\t\tbreak;\n-\t\t/*\n-\t\t * This is a random value.  It is only necessary that\n-\t\t * the next TMP_MAX values generated by adding 7777 to\n-\t\t * VALUE are different with (module 2^32).\n-\t\t */\n-\t\tvalue += 7777;\n-\t}\n-\t/* We return the null string if we can't find a unique file name.  */\n-\tpattern[0] = '\\0';\n-\treturn -1;\n-}\n-\n-int git_mkstemp_mode(char *pattern, int mode)\n-{\n-\t/* mkstemp is just mkstemps with no suffix */\n-\treturn git_mkstemps_mode(pattern, 0, mode);\n-}\n-\n-int gitmkstemps(char *pattern, int suffix_len)\n-{\n-\treturn git_mkstemps_mode(pattern, suffix_len, 0600);\n-}\n-\n int validate_headref(const char *path)\n {\n \tstruct stat st;\ndiff --git a/wrapper.c b/wrapper.c\nindex e67b70a..b3efefb 100644\n--- a/wrapper.c\n+++ b/wrapper.c\n@@ -204,6 +204,119 @@ int xmkstemp(char *template)\n \treturn fd;\n }\n \n+/* git_mkstemp() - create tmp file honoring TMPDIR variable */\n+int git_mkstemp(char *path, size_t len, const char *template)\n+{\n+\tconst char *tmp;\n+\tsize_t n;\n+\n+\ttmp = getenv(\"TMPDIR\");\n+\tif (!tmp)\n+\t\ttmp = \"/tmp\";\n+\tn = snprintf(path, len, \"%s/%s\", tmp, template);\n+\tif (len <= n) {\n+\t\terrno = ENAMETOOLONG;\n+\t\treturn -1;\n+\t}\n+\treturn mkstemp(path);\n+}\n+\n+/* git_mkstemps() - create tmp file with suffix honoring TMPDIR variable. */\n+int git_mkstemps(char *path, size_t len, const char *template, int suffix_len)\n+{\n+\tconst char *tmp;\n+\tsize_t n;\n+\n+\ttmp = getenv(\"TMPDIR\");\n+\tif (!tmp)\n+\t\ttmp = \"/tmp\";\n+\tn = snprintf(path, len, \"%s/%s\", tmp, template);\n+\tif (len <= n) {\n+\t\terrno = ENAMETOOLONG;\n+\t\treturn -1;\n+\t}\n+\treturn mkstemps(path, suffix_len);\n+}\n+\n+/* Adapted from libiberty's mkstemp.c. */\n+\n+#undef TMP_MAX\n+#define TMP_MAX 16384\n+\n+int git_mkstemps_mode(char *pattern, int suffix_len, int mode)\n+{\n+\tstatic const char letters[] =\n+\t\t\"abcdefghijklmnopqrstuvwxyz\"\n+\t\t\"ABCDEFGHIJKLMNOPQRSTUVWXYZ\"\n+\t\t\"0123456789\";\n+\tstatic const int num_letters = 62;\n+\tuint64_t value;\n+\tstruct timeval tv;\n+\tchar *template;\n+\tsize_t len;\n+\tint fd, count;\n+\n+\tlen = strlen(pattern);\n+\n+\tif (len < 6 + suffix_len) {\n+\t\terrno = EINVAL;\n+\t\treturn -1;\n+\t}\n+\n+\tif (strncmp(&pattern[len - 6 - suffix_len], \"XXXXXX\", 6)) {\n+\t\terrno = EINVAL;\n+\t\treturn -1;\n+\t}\n+\n+\t/*\n+\t * Replace pattern's XXXXXX characters with randomness.\n+\t * Try TMP_MAX different filenames.\n+\t */\n+\tgettimeofday(&tv, NULL);\n+\tvalue = ((size_t)(tv.tv_usec << 16)) ^ tv.tv_sec ^ getpid();\n+\ttemplate = &pattern[len - 6 - suffix_len];\n+\tfor (count = 0; count < TMP_MAX; ++count) {\n+\t\tuint64_t v = value;\n+\t\t/* Fill in the random bits. */\n+\t\ttemplate[0] = letters[v % num_letters]; v /= num_letters;\n+\t\ttemplate[1] = letters[v % num_letters]; v /= num_letters;\n+\t\ttemplate[2] = letters[v % num_letters]; v /= num_letters;\n+\t\ttemplate[3] = letters[v % num_letters]; v /= num_letters;\n+\t\ttemplate[4] = letters[v % num_letters]; v /= num_letters;\n+\t\ttemplate[5] = letters[v % num_letters]; v /= num_letters;\n+\n+\t\tfd = open(pattern, O_CREAT | O_EXCL | O_RDWR, mode);\n+\t\tif (fd > 0)\n+\t\t\treturn fd;\n+\t\t/*\n+\t\t * Fatal error (EPERM, ENOSPC etc).\n+\t\t * It doesn't make sense to loop.\n+\t\t */\n+\t\tif (errno != EEXIST)\n+\t\t\tbreak;\n+\t\t/*\n+\t\t * This is a random value.  It is only necessary that\n+\t\t * the next TMP_MAX values generated by adding 7777 to\n+\t\t * VALUE are different with (module 2^32).\n+\t\t */\n+\t\tvalue += 7777;\n+\t}\n+\t/* We return the null string if we can't find a unique file name.  */\n+\tpattern[0] = '\\0';\n+\treturn -1;\n+}\n+\n+int git_mkstemp_mode(char *pattern, int mode)\n+{\n+\t/* mkstemp is just mkstemps with no suffix */\n+\treturn git_mkstemps_mode(pattern, 0, mode);\n+}\n+\n+int gitmkstemps(char *pattern, int suffix_len)\n+{\n+\treturn git_mkstemps_mode(pattern, suffix_len, 0600);\n+}\n+\n int xmkstemp_mode(char *template, int mode)\n {\n \tint fd;\n-- \n1.7.2.3.557.gab647.dirty\n"},{"id":"155291","messageId":"20101106114652.GD27641@burratino","threadId":"25654","inReplyTo":"20101106113905.GA27405@burratino","subject":"[PATCH 4/8] strbuf: move strbuf_branchname to sha1_name.c","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-11-06T11:46:52Z","receivedAt":"2010-11-06T11:46:52Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"strbuf_branchname is a thin wrapper around interpret_branch_name\nfrom sha1_name.o.  Most strbuf.o users do not need it.\n\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\n---\n sha1_name.c |   16 ++++++++++++++++\n strbuf.c    |   16 ----------------\n 2 files changed, 16 insertions(+), 16 deletions(-)\n\ndiff --git a/sha1_name.c b/sha1_name.c\nindex 484081d..1beebe9 100644\n--- a/sha1_name.c\n+++ b/sha1_name.c\n@@ -934,6 +934,22 @@ int interpret_branch_name(const char *name, struct strbuf *buf)\n \treturn len;\n }\n \n+int strbuf_branchname(struct strbuf *sb, const char *name)\n+{\n+\tint len = strlen(name);\n+\tif (interpret_branch_name(name, sb) == len)\n+\t\treturn 0;\n+\tstrbuf_add(sb, name, len);\n+\treturn len;\n+}\n+\n+int strbuf_check_branch_ref(struct strbuf *sb, const char *name)\n+{\n+\tstrbuf_branchname(sb, name);\n+\tstrbuf_splice(sb, 0, 0, \"refs/heads/\", 11);\n+\treturn check_ref_format(sb->buf);\n+}\n+\n /*\n  * This is like \"get_sha1_basic()\", except it allows \"sha1 expressions\",\n  * notably \"xyz^\" for \"parent of xyz\"\ndiff --git a/strbuf.c b/strbuf.c\nindex bc3a080..9b3c445 100644\n--- a/strbuf.c\n+++ b/strbuf.c\n@@ -386,19 +386,3 @@ int strbuf_read_file(struct strbuf *sb, const char *path, size_t hint)\n \n \treturn len;\n }\n-\n-int strbuf_branchname(struct strbuf *sb, const char *name)\n-{\n-\tint len = strlen(name);\n-\tif (interpret_branch_name(name, sb) == len)\n-\t\treturn 0;\n-\tstrbuf_add(sb, name, len);\n-\treturn len;\n-}\n-\n-int strbuf_check_branch_ref(struct strbuf *sb, const char *name)\n-{\n-\tstrbuf_branchname(sb, name);\n-\tstrbuf_splice(sb, 0, 0, \"refs/heads/\", 11);\n-\treturn check_ref_format(sb->buf);\n-}\n-- \n1.7.2.3.557.gab647.dirty\n"},{"id":"155292","messageId":"20101106114734.GE27641@burratino","threadId":"25654","inReplyTo":"20101106113905.GA27405@burratino","subject":"[PATCH 5/8] wrapper: give zlib wrappers their own translation unit","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-11-06T11:47:34Z","receivedAt":"2010-11-06T11:47:34Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Programs using xmalloc() but not git_inflate() require -lz on the\nlinker command line because git_inflate() is in the same translation\nunit as xmalloc().\n\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\n---\n Makefile  |    1 +\n wrapper.c |   60 ------------------------------------------------------------\n zlib.c    |   61 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n 3 files changed, 62 insertions(+), 60 deletions(-)\n create mode 100644 zlib.c\n\ndiff --git a/Makefile b/Makefile\nindex d3dcfb1..45d03f8 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -659,6 +659,7 @@ LIB_OBJS += write_or_die.o\n LIB_OBJS += ws.o\n LIB_OBJS += wt-status.o\n LIB_OBJS += xdiff-interface.o\n+LIB_OBJS += zlib.o\n \n BUILTIN_OBJS += builtin/add.o\n BUILTIN_OBJS += builtin/annotate.o\ndiff --git a/wrapper.c b/wrapper.c\nindex b3efefb..185dfbc 100644\n--- a/wrapper.c\n+++ b/wrapper.c\n@@ -327,66 +327,6 @@ int xmkstemp_mode(char *template, int mode)\n \treturn fd;\n }\n \n-/*\n- * zlib wrappers to make sure we don't silently miss errors\n- * at init time.\n- */\n-void git_inflate_init(z_streamp strm)\n-{\n-\tconst char *err;\n-\n-\tswitch (inflateInit(strm)) {\n-\tcase Z_OK:\n-\t\treturn;\n-\n-\tcase Z_MEM_ERROR:\n-\t\terr = \"out of memory\";\n-\t\tbreak;\n-\tcase Z_VERSION_ERROR:\n-\t\terr = \"wrong version\";\n-\t\tbreak;\n-\tdefault:\n-\t\terr = \"error\";\n-\t}\n-\tdie(\"inflateInit: %s (%s)\", err, strm->msg ? strm->msg : \"no message\");\n-}\n-\n-void git_inflate_end(z_streamp strm)\n-{\n-\tif (inflateEnd(strm) != Z_OK)\n-\t\terror(\"inflateEnd: %s\", strm->msg ? strm->msg : \"failed\");\n-}\n-\n-int git_inflate(z_streamp strm, int flush)\n-{\n-\tint ret = inflate(strm, flush);\n-\tconst char *err;\n-\n-\tswitch (ret) {\n-\t/* Out of memory is fatal. */\n-\tcase Z_MEM_ERROR:\n-\t\tdie(\"inflate: out of memory\");\n-\n-\t/* Data corruption errors: we may want to recover from them (fsck) */\n-\tcase Z_NEED_DICT:\n-\t\terr = \"needs dictionary\"; break;\n-\tcase Z_DATA_ERROR:\n-\t\terr = \"data stream error\"; break;\n-\tcase Z_STREAM_ERROR:\n-\t\terr = \"stream consistency error\"; break;\n-\tdefault:\n-\t\terr = \"unknown error\"; break;\n-\n-\t/* Z_BUF_ERROR: normal, needs more space in the output buffer */\n-\tcase Z_BUF_ERROR:\n-\tcase Z_OK:\n-\tcase Z_STREAM_END:\n-\t\treturn ret;\n-\t}\n-\terror(\"inflate: %s (%s)\", err, strm->msg ? strm->msg : \"no message\");\n-\treturn ret;\n-}\n-\n static int warn_if_unremovable(const char *op, const char *file, int rc)\n {\n \tif (rc < 0) {\ndiff --git a/zlib.c b/zlib.c\nnew file mode 100644\nindex 0000000..c4d58da\n--- /dev/null\n+++ b/zlib.c\n@@ -0,0 +1,61 @@\n+/*\n+ * zlib wrappers to make sure we don't silently miss errors\n+ * at init time.\n+ */\n+#include \"cache.h\"\n+\n+void git_inflate_init(z_streamp strm)\n+{\n+\tconst char *err;\n+\n+\tswitch (inflateInit(strm)) {\n+\tcase Z_OK:\n+\t\treturn;\n+\n+\tcase Z_MEM_ERROR:\n+\t\terr = \"out of memory\";\n+\t\tbreak;\n+\tcase Z_VERSION_ERROR:\n+\t\terr = \"wrong version\";\n+\t\tbreak;\n+\tdefault:\n+\t\terr = \"error\";\n+\t}\n+\tdie(\"inflateInit: %s (%s)\", err, strm->msg ? strm->msg : \"no message\");\n+}\n+\n+void git_inflate_end(z_streamp strm)\n+{\n+\tif (inflateEnd(strm) != Z_OK)\n+\t\terror(\"inflateEnd: %s\", strm->msg ? strm->msg : \"failed\");\n+}\n+\n+int git_inflate(z_streamp strm, int flush)\n+{\n+\tint ret = inflate(strm, flush);\n+\tconst char *err;\n+\n+\tswitch (ret) {\n+\t/* Out of memory is fatal. */\n+\tcase Z_MEM_ERROR:\n+\t\tdie(\"inflate: out of memory\");\n+\n+\t/* Data corruption errors: we may want to recover from them (fsck) */\n+\tcase Z_NEED_DICT:\n+\t\terr = \"needs dictionary\"; break;\n+\tcase Z_DATA_ERROR:\n+\t\terr = \"data stream error\"; break;\n+\tcase Z_STREAM_ERROR:\n+\t\terr = \"stream consistency error\"; break;\n+\tdefault:\n+\t\terr = \"unknown error\"; break;\n+\n+\t/* Z_BUF_ERROR: normal, needs more space in the output buffer */\n+\tcase Z_BUF_ERROR:\n+\tcase Z_OK:\n+\tcase Z_STREAM_END:\n+\t\treturn ret;\n+\t}\n+\terror(\"inflate: %s (%s)\", err, strm->msg ? strm->msg : \"no message\");\n+\treturn ret;\n+}\n-- \n1.7.2.3.557.gab647.dirty\n"},{"id":"155293","messageId":"20101106114757.GF27641@burratino","threadId":"25654","inReplyTo":"20101106113905.GA27405@burratino","subject":"[PATCH 6/8] pack-objects: mark file-local variable static","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-11-06T11:47:57Z","receivedAt":"2010-11-06T11:47:57Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"old_try_to_free_routine is not meant for use from other files.\n\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\n---\n builtin/pack-objects.c |    2 +-\n 1 files changed, 1 insertions(+), 1 deletions(-)\n\ndiff --git a/builtin/pack-objects.c b/builtin/pack-objects.c\nindex f8eba53..7471c92 100644\n--- a/builtin/pack-objects.c\n+++ b/builtin/pack-objects.c\n@@ -1529,7 +1529,7 @@ static void try_to_free_from_threads(size_t size)\n \tread_unlock();\n }\n \n-try_to_free_t old_try_to_free_routine;\n+static try_to_free_t old_try_to_free_routine;\n \n /*\n  * The main thread waits on the condition that (at least) one of the workers\n-- \n1.7.2.3.557.gab647.dirty\n"},{"id":"155294","messageId":"20101106114817.GG27641@burratino","threadId":"25654","inReplyTo":"20101106113905.GA27405@burratino","subject":"[PATCH 7/8] wrapper: expose try_to_free_pack_memory()","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-11-06T11:48:17Z","receivedAt":"2010-11-06T11:48:17Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"As v1.7.0-rc0~43 (slim down \"git show-index\", 2010-01-21) explains,\nxmalloc() is dependent on zlib, the sha1 lib, and the rest of git's\nobject file access machinery via try_to_free_pack_memory.  That is\noverkill when xmalloc() is only being used to print a message and exit\non memory exhaustion.\n\nSo let each caller decide whether the \"discard pack windows\" logic is\nneeded.  Programs using the sha1_file library should request that\nxmalloc discard stale windows when an allocation fails, by calling\n\n\tset_try_to_free_handler(try_to_free_pack_memory);\n\nA later patch will stop setting up that handler except in response to\nsuch explicit requests, allowing wrapper.o to be used without adding a\nsha1_file.o dependency by programs that do not access the object db.\n\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\n---\n git-compat-util.h |    1 +\n sha1_file.c       |    5 +++++\n wrapper.c         |    7 +------\n 3 files changed, 7 insertions(+), 6 deletions(-)\n\ndiff --git a/git-compat-util.h b/git-compat-util.h\nindex 029162e..07ee75e 100644\n--- a/git-compat-util.h\n+++ b/git-compat-util.h\n@@ -387,6 +387,7 @@ static inline void *gitmempcpy(void *dest, const void *src, size_t n)\n #endif\n \n extern void release_pack_memory(size_t, int);\n+extern void try_to_free_pack_memory(size_t size);\n \n typedef void (*try_to_free_t)(size_t);\n extern try_to_free_t set_try_to_free_routine(try_to_free_t);\ndiff --git a/sha1_file.c b/sha1_file.c\nindex 8e299ae..c48baaa 100644\n--- a/sha1_file.c\n+++ b/sha1_file.c\n@@ -576,6 +576,11 @@ void release_pack_memory(size_t need, int fd)\n \t\t; /* nothing */\n }\n \n+void try_to_free_pack_memory(size_t size)\n+{\n+\trelease_pack_memory(size, -1);\n+}\n+\n void *xmmap(void *start, size_t length,\n \tint prot, int flags, int fd, off_t offset)\n {\ndiff --git a/wrapper.c b/wrapper.c\nindex 185dfbc..6c6579b 100644\n--- a/wrapper.c\n+++ b/wrapper.c\n@@ -3,12 +3,7 @@\n  */\n #include \"cache.h\"\n \n-static void try_to_free_builtin(size_t size)\n-{\n-\trelease_pack_memory(size, -1);\n-}\n-\n-static void (*try_to_free_routine)(size_t size) = try_to_free_builtin;\n+static void (*try_to_free_routine)(size_t size) = try_to_free_pack_memory;\n \n try_to_free_t set_try_to_free_routine(try_to_free_t routine)\n {\n-- \n1.7.2.3.557.gab647.dirty\n"},{"id":"155295","messageId":"20101106115237.GH27641@burratino","threadId":"25654","inReplyTo":"20101106113905.GA27405@burratino","subject":"[PATCH 8/8] Remove pack file handling dependency from wrapper.o","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-11-06T11:52:37Z","receivedAt":"2010-11-06T11:52:37Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Commands that might access a git repository should discard pack\nwindows when memory is tight, but helpers like show-index do not need\nto.\n\nSo stop setting try_to_free_pack_memory as the default\ntry_to_free_routine and instead set up the try_to_free handler\nexplicitly in main() for callers that require it.\n\nAfter this change, a simple program using xmalloc() and no other\nfunctions will not pull in any code from libgit.a aside from wrapper.o\nand usage.o.\n\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\n---\nThanks for reading.  I hope it was not too dull.\n\nHopefully this will make svn-fe small again (it got big when the\nvcs-svn lib started using strbufs).\n\nGood night,\nJonathan\n\n check-racy.c                              |    1 +\n contrib/convert-objects/convert-objects.c |    1 +\n daemon.c                                  |    1 +\n fast-import.c                             |    1 +\n git.c                                     |    2 ++\n http-backend.c                            |    1 +\n http-fetch.c                              |    1 +\n http-push.c                               |    1 +\n imap-send.c                               |    1 +\n remote-curl.c                             |    1 +\n test-dump-cache-tree.c                    |    4 +++-\n test-match-trees.c                        |    1 +\n upload-pack.c                             |    1 +\n wrapper.c                                 |    6 +++++-\n 14 files changed, 21 insertions(+), 2 deletions(-)\n\ndiff --git a/check-racy.c b/check-racy.c\nindex 00d92a1..d4b2557 100644\n--- a/check-racy.c\n+++ b/check-racy.c\n@@ -6,6 +6,7 @@ int main(int ac, char **av)\n \tint dirty, clean, racy;\n \n \tdirty = clean = racy = 0;\n+\tset_try_to_free_routine(try_to_free_pack_memory);\n \tread_cache();\n \tfor (i = 0; i < active_nr; i++) {\n \t\tstruct cache_entry *ce = active_cache[i];\ndiff --git a/contrib/convert-objects/convert-objects.c b/contrib/convert-objects/convert-objects.c\nindex f3b57bf..983b917 100644\n--- a/contrib/convert-objects/convert-objects.c\n+++ b/contrib/convert-objects/convert-objects.c\n@@ -317,6 +317,7 @@ int main(int argc, char **argv)\n \tstruct entry *entry;\n \n \tsetup_git_directory();\n+\tset_try_to_free_routine(try_to_free_pack_memory);\n \n \tif (argc != 2)\n \t\tusage(\"git-convert-objects <sha1>\");\ndiff --git a/daemon.c b/daemon.c\nindex 9326d3a..ccf8960 100644\n--- a/daemon.c\n+++ b/daemon.c\n@@ -976,6 +976,7 @@ int main(int argc, char **argv)\n \tint i;\n \n \tgit_extract_argv0_path(argv[0]);\n+\tset_try_to_free_routine(try_to_free_pack_memory);\n \n \tfor (i = 1; i < argc; i++) {\n \t\tchar *arg = argv[i];\ndiff --git a/fast-import.c b/fast-import.c\nindex eab68d5..ccf81b1 100644\n--- a/fast-import.c\n+++ b/fast-import.c\n@@ -2917,6 +2917,7 @@ int main(int argc, const char **argv)\n \tunsigned int i;\n \n \tgit_extract_argv0_path(argv[0]);\n+\tset_try_to_free_routine(try_to_free_pack_memory);\n \n \tif (argc == 2 && !strcmp(argv[1], \"-h\"))\n \t\tusage(fast_import_usage);\ndiff --git a/git.c b/git.c\nindex 0409ac9..6386404 100644\n--- a/git.c\n+++ b/git.c\n@@ -272,6 +272,8 @@ static int run_builtin(struct cmd_struct *p, int argc, const char **argv)\n \n \ttrace_argv_printf(argv, \"trace: built-in: git\");\n \n+\tset_try_to_free_routine(try_to_free_pack_memory);\n+\n \tstatus = p->fn(argc, argv, prefix);\n \tif (status)\n \t\treturn status;\ndiff --git a/http-backend.c b/http-backend.c\nindex 14c90c2..7d02e55 100644\n--- a/http-backend.c\n+++ b/http-backend.c\n@@ -551,6 +551,7 @@ int main(int argc, char **argv)\n \tint i;\n \n \tgit_extract_argv0_path(argv[0]);\n+\tset_try_to_free_routine(try_to_free_pack_memory);\n \tset_die_routine(die_webcgi);\n \n \tif (!method)\ndiff --git a/http-fetch.c b/http-fetch.c\nindex 762c750..98cefc7 100644\n--- a/http-fetch.c\n+++ b/http-fetch.c\n@@ -25,6 +25,7 @@ int main(int argc, const char **argv)\n \tint get_recover = 0;\n \n \tgit_extract_argv0_path(argv[0]);\n+\tset_try_to_free_routine(try_to_free_pack_memory);\n \n \twhile (arg < argc && argv[arg][0] == '-') {\n \t\tif (argv[arg][1] == 't') {\ndiff --git a/http-push.c b/http-push.c\nindex c9bcd11..fc25aeb 100644\n--- a/http-push.c\n+++ b/http-push.c\n@@ -1792,6 +1792,7 @@ int main(int argc, char **argv)\n \tchar *rewritten_url = NULL;\n \n \tgit_extract_argv0_path(argv[0]);\n+\tset_try_to_free_routine(try_to_free_pack_memory);\n \n \trepo = xcalloc(sizeof(*repo), 1);\n \ndiff --git a/imap-send.c b/imap-send.c\nindex 71506a8..8056144 100644\n--- a/imap-send.c\n+++ b/imap-send.c\n@@ -1538,6 +1538,7 @@ int main(int argc, char **argv)\n \tint nongit_ok;\n \n \tgit_extract_argv0_path(argv[0]);\n+\tset_try_to_free_routine(try_to_free_pack_memory);\n \n \tif (argc != 1)\n \t\tusage(imap_send_usage);\ndiff --git a/remote-curl.c b/remote-curl.c\nindex 04d4813..4c2b03a 100644\n--- a/remote-curl.c\n+++ b/remote-curl.c\n@@ -788,6 +788,7 @@ int main(int argc, const char **argv)\n \tint nongit;\n \n \tgit_extract_argv0_path(argv[0]);\n+\tset_try_to_free_routine(try_to_free_pack_memory);\n \tsetup_git_directory_gently(&nongit);\n \tif (argc < 2) {\n \t\tfprintf(stderr, \"Remote needed\\n\");\ndiff --git a/test-dump-cache-tree.c b/test-dump-cache-tree.c\nindex 1f73f1e..a6faa89 100644\n--- a/test-dump-cache-tree.c\n+++ b/test-dump-cache-tree.c\n@@ -56,7 +56,9 @@ static int dump_cache_tree(struct cache_tree *it,\n \n int main(int ac, char **av)\n {\n-\tstruct cache_tree *another = cache_tree();\n+\tstruct cache_tree *another;\n+\tset_try_to_free_routine(try_to_free_pack_memory);\n+\tanother = cache_tree();\n \tif (read_cache() < 0)\n \t\tdie(\"unable to read index file\");\n \tcache_tree_update(another, active_cache, active_nr, 0, 1);\ndiff --git a/test-match-trees.c b/test-match-trees.c\nindex a3c4688..c543fee 100644\n--- a/test-match-trees.c\n+++ b/test-match-trees.c\n@@ -6,6 +6,7 @@ int main(int ac, char **av)\n \tunsigned char hash1[20], hash2[20], shifted[20];\n \tstruct tree *one, *two;\n \n+\tset_try_to_free_routine(try_to_free_pack_memory);\n \tif (get_sha1(av[1], hash1))\n \t\tdie(\"cannot parse %s as an object name\", av[1]);\n \tif (get_sha1(av[2], hash2))\ndiff --git a/upload-pack.c b/upload-pack.c\nindex f05e422..d654e8b 100644\n--- a/upload-pack.c\n+++ b/upload-pack.c\n@@ -683,6 +683,7 @@ int main(int argc, char **argv)\n \tint strict = 0;\n \n \tgit_extract_argv0_path(argv[0]);\n+\tset_try_to_free_routine(try_to_free_pack_memory);\n \tread_replace_refs = 0;\n \n \tfor (i = 1; i < argc; i++) {\ndiff --git a/wrapper.c b/wrapper.c\nindex 6c6579b..4c1639f 100644\n--- a/wrapper.c\n+++ b/wrapper.c\n@@ -3,7 +3,11 @@\n  */\n #include \"cache.h\"\n \n-static void (*try_to_free_routine)(size_t size) = try_to_free_pack_memory;\n+static void do_nothing(size_t size)\n+{\n+}\n+\n+static void (*try_to_free_routine)(size_t size) = do_nothing;\n \n try_to_free_t set_try_to_free_routine(try_to_free_t routine)\n {\n-- \n1.7.2.3.557.gab647.dirty\n"},{"id":"155298","messageId":"4CD5996F.6010809@lsrfire.ath.cx","threadId":"25654","inReplyTo":"20101106115237.GH27641@burratino","subject":"Re: [PATCH 8/8] Remove pack file handling dependency from wrapper.o","fromName":"René Scharfe","fromEmail":"rene.scharfe@lsrfire.ath.cx","sentAt":"2010-11-06T18:07:43Z","receivedAt":"2010-11-06T18:07:43Z","isPatch":true,"sender":{"key":"l.s.r@web.de","avatar":"https://avatars.githubusercontent.com/u/26122331?v=4"},"body":"Am 06.11.2010 12:52, schrieb Jonathan Nieder:\n> Commands that might access a git repository should discard pack\n> windows when memory is tight, but helpers like show-index do not need\n> to.\n> \n> So stop setting try_to_free_pack_memory as the default\n> try_to_free_routine and instead set up the try_to_free handler\n> explicitly in main() for callers that require it.\n\nUgh.  Having to remember setting this handler is tedious.\n\nCan it be set automatically once the first pack is loaded?  A quick look\nsuggests that use_pack() would be the right place to do it.\n\nRené\n"},{"id":"155299","messageId":"20101106184251.GA14288@burratino","threadId":"25654","inReplyTo":"4CD5996F.6010809@lsrfire.ath.cx","subject":"Re: [PATCH 8/8] Remove pack file handling dependency from wrapper.o","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-11-06T18:42:51Z","receivedAt":"2010-11-06T18:42:51Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"René Scharfe wrote:\n\n> Ugh.  Having to remember setting this handler is tedious.\n> \n> Can it be set automatically once the first pack is loaded?  A quick look\n> suggests that use_pack() would be the right place to do it.\n\nMaybe add_packed_git()?\n\nuse_pack() is called by:\n\n pack-objects::check_pack_inflate\n pack-objects::copy_pack_data\n pack-objects::check_object\n check_pack_crc\n verify_pack\n get_size_from_delta\n sha1_file::get_delta_base\n sha1_file::unpack_object_header\n packed_object_info_detail\n sha1_file::unpack_compressed_entry\n\nsome of which would make me worry about thread-safety.\n"},{"id":"155300","messageId":"20101106190038.GB14288@burratino","threadId":"25654","inReplyTo":"4CD5996F.6010809@lsrfire.ath.cx","subject":"Re: [PATCH 8/8] Remove pack file handling dependency from wrapper.o","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-11-06T19:00:38Z","receivedAt":"2010-11-06T19:00:38Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"René Scharfe wrote:\n\n> Can it be set automatically once the first pack is loaded?  A quick look\n> suggests that use_pack() would be the right place to do it.\n\nHow about this?  Replaces patches 7 and 8.\n\n--8 <--\nSubject: Remove pack file handling dependency from wrapper.o\n\nAs v1.7.0-rc0~43 (slim down \"git show-index\", 2010-01-21) explains,\nuse of xmalloc() brings in a dependency on zlib, the sha1 lib, and the\nrest of git's object file access machinery via try_to_free_pack_memory.\nThat is overkill when xmalloc is just being used as a convenience\nwrapper to exit when no memory is available.\n\nSo defer setting try_to_free_pack_memory as try_to_free_routine until\nthe first packfile is opened in add_packed_git().\n\nAfter this change, a simple program using xmalloc() and no other\nfunctions will not pull in any code from libgit.a aside from wrapper.o\nand usage.o.\n\nImproved-by: René Scharfe <rene.scharfe@lsrfire.ath.cx>\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\n---\n sha1_file.c |   11 +++++++++++\n wrapper.c   |    5 ++---\n 2 files changed, 13 insertions(+), 3 deletions(-)\n\ndiff --git a/sha1_file.c b/sha1_file.c\nindex 8e299ae..e0d2496 100644\n--- a/sha1_file.c\n+++ b/sha1_file.c\n@@ -818,11 +818,22 @@ static struct packed_git *alloc_packed_git(int extra)\n \treturn p;\n }\n \n+static void try_to_free_pack_memory(size_t size)\n+{\n+\trelease_pack_memory(size, -1);\n+}\n+\n struct packed_git *add_packed_git(const char *path, int path_len, int local)\n {\n+\tstatic int have_set_try_to_free_routine;\n \tstruct stat st;\n \tstruct packed_git *p = alloc_packed_git(path_len + 2);\n \n+\tif (!have_set_try_to_free_routine) {\n+\t\thave_set_try_to_free_routine = 1;\n+\t\tset_try_to_free_routine(try_to_free_pack_memory);\n+\t}\n+\n \t/*\n \t * Make sure a corresponding .pack file exists and that\n \t * the index looks sane.\ndiff --git a/wrapper.c b/wrapper.c\nindex 185dfbc..4c1639f 100644\n--- a/wrapper.c\n+++ b/wrapper.c\n@@ -3,12 +3,11 @@\n  */\n #include \"cache.h\"\n \n-static void try_to_free_builtin(size_t size)\n+static void do_nothing(size_t size)\n {\n-\trelease_pack_memory(size, -1);\n }\n \n-static void (*try_to_free_routine)(size_t size) = try_to_free_builtin;\n+static void (*try_to_free_routine)(size_t size) = do_nothing;\n \n try_to_free_t set_try_to_free_routine(try_to_free_t routine)\n {\n-- \n1.7.2.3.557.gab647.dirty\n"},{"id":"155331","messageId":"4CD6CF59.5040801@lsrfire.ath.cx","threadId":"25654","inReplyTo":"20101106184251.GA14288@burratino","subject":"Re: [PATCH 8/8] Remove pack file handling dependency from wrapper.o","fromName":"René Scharfe","fromEmail":"rene.scharfe@lsrfire.ath.cx","sentAt":"2010-11-07T16:10:01Z","receivedAt":"2010-11-07T16:10:01Z","isPatch":true,"sender":{"key":"l.s.r@web.de","avatar":"https://avatars.githubusercontent.com/u/26122331?v=4"},"body":"Am 06.11.2010 19:42, schrieb Jonathan Nieder:\n> René Scharfe wrote:\n> \n>> Ugh.  Having to remember setting this handler is tedious.\n>>\n>> Can it be set automatically once the first pack is loaded?  A quick look\n>> suggests that use_pack() would be the right place to do it.\n> \n> Maybe add_packed_git()?\n> \n> use_pack() is called by:\n> \n>  pack-objects::check_pack_inflate\n>  pack-objects::copy_pack_data\n>  pack-objects::check_object\n>  check_pack_crc\n>  verify_pack\n>  get_size_from_delta\n>  sha1_file::get_delta_base\n>  sha1_file::unpack_object_header\n>  packed_object_info_detail\n>  sha1_file::unpack_compressed_entry\n> \n> some of which would make me worry about thread-safety.\n\nPossibly, but if that's the case then we have a thread-safety issue\nalready: use_pack() updates pack_mapped, which is used by\nrelease_pack_memory() to see how much can be freed.  Just saying.\n\nRené\n"},{"id":"155339","messageId":"20101107182341.GA31470@burratino","threadId":"25654","inReplyTo":"4CD6CF59.5040801@lsrfire.ath.cx","subject":"Re: [PATCH 8/8] Remove pack file handling dependency from wrapper.o","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-11-07T18:23:41Z","receivedAt":"2010-11-07T18:23:41Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"René Scharfe wrote:\n> Am 06.11.2010 19:42, schrieb Jonathan Nieder:\n\n>> Maybe add_packed_git()?\n>> \n>> use_pack() is called by:\n[...]\n>> some of which would make me worry about thread-safety.\n>\n> Possibly, but if that's the case then we have a thread-safety issue\n> already: use_pack() updates pack_mapped, which is used by\n> release_pack_memory() to see how much can be freed.\n\nGood point.  The threaded callers are probably protected by read_lock.\n\nMy other worry would be that try_to_free_pack_memory should not\noverride try_to_free_from_threads.  I guess some time documenting\nthese code paths will be needed. :(\n\nThanks for a sanity check,\nJonathan\n"}]}