From 27ca0db7a6143d2e479ff1ae52ec7c349ab1d4f2 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Tue, 7 Jan 2014 23:33:46 +0100 Subject: util/Alloc: new library replacing GLib's g_malloc() --- src/DecoderBuffer.cxx | 1 + src/Directory.cxx | 10 ++--- src/Page.cxx | 10 ++--- src/PlaylistSave.cxx | 7 ++-- src/Song.cxx | 10 ++--- src/UpdateWalk.cxx | 8 ++-- src/cue/CueParser.cxx | 7 ++-- src/decoder/GmeDecoderPlugin.cxx | 5 ++- src/decoder/SidplayDecoderPlugin.cxx | 7 ++-- src/event/ServerSocket.cxx | 7 ++-- src/input/ArchiveInputPlugin.cxx | 13 +++--- src/output/OSXOutputPlugin.cxx | 2 +- src/tag/TagBuilder.cxx | 5 +-- src/tag/TagConfig.cxx | 7 +++- src/tag/TagPool.cxx | 1 + src/tag/TagString.cxx | 15 ++++--- src/util/Alloc.cxx | 76 ++++++++++++++++++++++++++++++++++++ src/util/Alloc.hxx | 67 +++++++++++++++++++++++++++++++ src/util/VarSize.hxx | 7 ++-- 19 files changed, 208 insertions(+), 57 deletions(-) create mode 100644 src/util/Alloc.cxx create mode 100644 src/util/Alloc.hxx (limited to 'src') diff --git a/src/DecoderBuffer.cxx b/src/DecoderBuffer.cxx index 0f592b020..18fd3aa5c 100644 --- a/src/DecoderBuffer.cxx +++ b/src/DecoderBuffer.cxx @@ -25,6 +25,7 @@ #include #include +#include struct DecoderBuffer { Decoder *decoder; diff --git a/src/Directory.cxx b/src/Directory.cxx index f9c1e2ba4..750fee896 100644 --- a/src/Directory.cxx +++ b/src/Directory.cxx @@ -174,7 +174,7 @@ Directory::LookupDirectory(const char *uri) if (isRootDirectory(uri)) return this; - char *duplicated = g_strdup(uri), *name = duplicated; + char *duplicated = xstrdup(uri), *name = duplicated; Directory *d = this; while (1) { @@ -194,7 +194,7 @@ Directory::LookupDirectory(const char *uri) name = slash + 1; } - g_free(duplicated); + free(duplicated); return d; } @@ -244,7 +244,7 @@ Directory::LookupSong(const char *uri) assert(holding_db_lock()); assert(uri != nullptr); - duplicated = g_strdup(uri); + duplicated = xstrdup(uri); base = strrchr(duplicated, '/'); Directory *d = this; @@ -252,7 +252,7 @@ Directory::LookupSong(const char *uri) *base++ = 0; d = d->LookupDirectory(duplicated); if (d == nullptr) { - g_free(duplicated); + free(duplicated); return nullptr; } } else @@ -261,7 +261,7 @@ Directory::LookupSong(const char *uri) Song *song = d->FindSong(base); assert(song == nullptr || song->parent == d); - g_free(duplicated); + free(duplicated); return song; } diff --git a/src/Page.cxx b/src/Page.cxx index 91033a1ec..c46d743ca 100644 --- a/src/Page.cxx +++ b/src/Page.cxx @@ -19,19 +19,19 @@ #include "config.h" #include "Page.hxx" - -#include +#include "util/Alloc.hxx" #include #include #include +#include Page * Page::Create(size_t size) { - void *p = g_malloc(sizeof(Page) + size - - sizeof(Page::data)); + void *p = xalloc(sizeof(Page) + size - + sizeof(Page::data)); return ::new(p) Page(size); } @@ -63,7 +63,7 @@ Page::Unref() if (unused) { this->Page::~Page(); - g_free(this); + free(this); } return unused; diff --git a/src/PlaylistSave.cxx b/src/PlaylistSave.cxx index 1006fdcc7..02195bd15 100644 --- a/src/PlaylistSave.cxx +++ b/src/PlaylistSave.cxx @@ -28,12 +28,11 @@ #include "fs/AllocatedPath.hxx" #include "fs/Traits.hxx" #include "fs/FileSystem.hxx" +#include "util/Alloc.hxx" #include "util/UriUtil.hxx" #include "util/Error.hxx" #include "Log.hxx" -#include - #include void @@ -127,7 +126,7 @@ playlist_load_spl(struct playlist &playlist, PlayerControl &pc, if ((playlist.AppendURI(pc, uri_utf8.c_str())) != PlaylistResult::SUCCESS) { /* for windows compatibility, convert slashes */ - char *temp2 = g_strdup(uri_utf8.c_str()); + char *temp2 = xstrdup(uri_utf8.c_str()); char *p = temp2; while (*p) { if (*p == '\\') @@ -139,7 +138,7 @@ playlist_load_spl(struct playlist &playlist, PlayerControl &pc, FormatError(playlist_domain, "can't add file \"%s\"", temp2); - g_free(temp2); + free(temp2); } } diff --git a/src/Song.cxx b/src/Song.cxx index 6213d5e66..ae0c70ab9 100644 --- a/src/Song.cxx +++ b/src/Song.cxx @@ -21,11 +21,11 @@ #include "Song.hxx" #include "Directory.hxx" #include "tag/Tag.hxx" - -#include +#include "util/Alloc.hxx" #include #include +#include Directory detached_root; @@ -39,7 +39,7 @@ song_alloc(const char *uri, Directory *parent) assert(uri_length); Song *song = (Song *) - g_malloc(sizeof(*song) - sizeof(song->uri) + uri_length + 1); + xalloc(sizeof(*song) - sizeof(song->uri) + uri_length + 1); song->tag = nullptr; memcpy(song->uri, uri, uri_length + 1); @@ -72,7 +72,7 @@ Song::ReplaceURI(const char *new_uri) new_song->mtime = mtime; new_song->start_ms = start_ms; new_song->end_ms = end_ms; - g_free(this); + free(this); return new_song; } @@ -106,7 +106,7 @@ void Song::Free() { delete tag; - g_free(this); + free(this); } void diff --git a/src/UpdateWalk.cxx b/src/UpdateWalk.cxx index 811978d52..3afcbbdf2 100644 --- a/src/UpdateWalk.cxx +++ b/src/UpdateWalk.cxx @@ -38,14 +38,14 @@ #include "fs/Traits.hxx" #include "fs/FileSystem.hxx" #include "fs/DirectoryReader.hxx" +#include "util/Alloc.hxx" #include "util/UriUtil.hxx" #include "Log.hxx" -#include - #include #include #include +#include #include bool walk_discard; @@ -426,7 +426,7 @@ static Directory * directory_make_uri_parent_checked(const char *uri) { Directory *directory = db_get_root(); - char *duplicated = g_strdup(uri); + char *duplicated = xstrdup(uri); char *name_utf8 = duplicated, *slash; while ((slash = strchr(name_utf8, '/')) != nullptr) { @@ -443,7 +443,7 @@ directory_make_uri_parent_checked(const char *uri) name_utf8 = slash + 1; } - g_free(duplicated); + free(duplicated); return directory; } diff --git a/src/cue/CueParser.cxx b/src/cue/CueParser.cxx index 7a226c849..b9927f5e2 100644 --- a/src/cue/CueParser.cxx +++ b/src/cue/CueParser.cxx @@ -19,13 +19,12 @@ #include "config.h" #include "CueParser.hxx" +#include "util/Alloc.hxx" #include "util/StringUtil.hxx" #include "util/CharUtil.hxx" #include "Song.hxx" #include "tag/Tag.hxx" -#include - #include #include #include @@ -290,9 +289,9 @@ CueParser::Feed(const char *line) assert(!end); assert(line != nullptr); - char *allocated = g_strdup(line); + char *allocated = xstrdup(line); Feed2(allocated); - g_free(allocated); + free(allocated); } void diff --git a/src/decoder/GmeDecoderPlugin.cxx b/src/decoder/GmeDecoderPlugin.cxx index 815fd8d69..aafc8f07d 100644 --- a/src/decoder/GmeDecoderPlugin.cxx +++ b/src/decoder/GmeDecoderPlugin.cxx @@ -22,6 +22,7 @@ #include "DecoderAPI.hxx" #include "CheckAudioFormat.hxx" #include "tag/TagHandler.hxx" +#include "util/Alloc.hxx" #include "util/FormatString.hxx" #include "util/UriUtil.hxx" #include "util/Error.hxx" @@ -53,7 +54,7 @@ static char * get_container_name(const char *path_fs) { const char *subtune_suffix = uri_get_suffix(path_fs); - char *path_container = g_strdup(path_fs); + char *path_container = xstrdup(path_fs); char pat[64]; snprintf(pat, sizeof(pat), "%s%s", @@ -137,7 +138,7 @@ gme_file_decode(Decoder &decoder, const char *path_fs) Music_Emu *emu; const char *gme_err = gme_open_file(path_container, &emu, GME_SAMPLE_RATE); - g_free(path_container); + free(path_container); if (gme_err != nullptr) { LogWarning(gme_domain, gme_err); return; diff --git a/src/decoder/SidplayDecoderPlugin.cxx b/src/decoder/SidplayDecoderPlugin.cxx index 160337594..9b3a4ad40 100644 --- a/src/decoder/SidplayDecoderPlugin.cxx +++ b/src/decoder/SidplayDecoderPlugin.cxx @@ -21,6 +21,7 @@ #include "SidplayDecoderPlugin.hxx" #include "../DecoderAPI.hxx" #include "tag/TagHandler.hxx" +#include "util/Alloc.hxx" #include "util/Domain.hxx" #include "system/ByteOrder.hxx" #include "Log.hxx" @@ -121,7 +122,7 @@ sidplay_finish() static char * get_container_name(const char *path_fs) { - char *path_container=g_strdup(path_fs); + char *path_container = strdup(path_fs); if(!g_pattern_match(path_with_subtune, strlen(path_container), path_container, nullptr)) @@ -163,9 +164,9 @@ get_song_length(const char *path_fs) if (songlength_database == nullptr) return -1; - gchar *sid_file=get_container_name(path_fs); + char *sid_file = get_container_name(path_fs); SidTuneMod tune(sid_file); - g_free(sid_file); + free(sid_file); if(!tune) { LogWarning(sidplay_domain, "failed to load file for calculating md5 sum"); diff --git a/src/event/ServerSocket.cxx b/src/event/ServerSocket.cxx index 64e38776f..11592b4fb 100644 --- a/src/event/ServerSocket.cxx +++ b/src/event/ServerSocket.cxx @@ -31,12 +31,11 @@ #include "system/fd_util.h" #include "fs/AllocatedPath.hxx" #include "fs/FileSystem.hxx" +#include "util/Alloc.hxx" #include "util/Error.hxx" #include "util/Domain.hxx" #include "Log.hxx" -#include - #include #include @@ -79,7 +78,7 @@ public: parent(_parent), serial(_serial), path(AllocatedPath::Null()), address_length(_address_length), - address((sockaddr *)g_memdup(_address, _address_length)) + address((sockaddr *)xmemdup(_address, _address_length)) { assert(_address != nullptr); assert(_address_length > 0); @@ -89,7 +88,7 @@ public: OneServerSocket &operator=(const OneServerSocket &other) = delete; ~OneServerSocket() { - g_free(address); + free(address); if (IsDefined()) Close(); diff --git a/src/input/ArchiveInputPlugin.cxx b/src/input/ArchiveInputPlugin.cxx index 5797caced..597a91604 100644 --- a/src/input/ArchiveInputPlugin.cxx +++ b/src/input/ArchiveInputPlugin.cxx @@ -26,9 +26,10 @@ #include "ArchiveFile.hxx" #include "InputPlugin.hxx" #include "fs/Traits.hxx" +#include "util/Alloc.hxx" #include "Log.hxx" -#include +#include /** * select correct archive plugin to handle the input stream @@ -49,13 +50,13 @@ input_archive_open(const char *pathname, if (!PathTraitsFS::IsAbsolute(pathname)) return nullptr; - char *pname = g_strdup(pathname); + char *pname = strdup(pathname); // archive_lookup will modify pname when true is returned const char *archive, *filename, *suffix; if (!archive_lookup(pname, &archive, &filename, &suffix)) { FormatDebug(archive_domain, "not an archive, lookup %s failed", pname); - g_free(pname); + free(pname); return nullptr; } @@ -64,19 +65,19 @@ input_archive_open(const char *pathname, if (!arplug) { FormatWarning(archive_domain, "can't handle archive %s", archive); - g_free(pname); + free(pname); return nullptr; } auto file = archive_file_open(arplug, archive, error); if (file == nullptr) { - g_free(pname); + free(pname); return nullptr; } //setup fileops is = file->OpenStream(filename, mutex, cond, error); - g_free(pname); + free(pname); file->Close(); return is; diff --git a/src/output/OSXOutputPlugin.cxx b/src/output/OSXOutputPlugin.cxx index 907cb0346..586210b21 100644 --- a/src/output/OSXOutputPlugin.cxx +++ b/src/output/OSXOutputPlugin.cxx @@ -72,7 +72,7 @@ osx_output_configure(OSXOutput *oo, const config_param ¶m) } else { oo->component_subtype = kAudioUnitSubType_HALOutput; - /* XXX am I supposed to g_strdup() this? */ + /* XXX am I supposed to strdup() this? */ oo->device_name = device; } } diff --git a/src/tag/TagBuilder.cxx b/src/tag/TagBuilder.cxx index 37aa08cee..3e6d2aeb8 100644 --- a/src/tag/TagBuilder.cxx +++ b/src/tag/TagBuilder.cxx @@ -24,10 +24,9 @@ #include "TagString.hxx" #include "Tag.hxx" -#include - #include #include +#include TagBuilder::TagBuilder(const Tag &other) :time(other.time), has_playlist(other.has_playlist) @@ -187,7 +186,7 @@ TagBuilder::AddItemInternal(TagType type, const char *value, size_t length) auto i = tag_pool_get_item(type, value, length); tag_pool_lock.unlock(); - g_free(p); + free(p); items.push_back(i); } diff --git a/src/tag/TagConfig.cxx b/src/tag/TagConfig.cxx index 0213ab4dc..5c81fa603 100644 --- a/src/tag/TagConfig.cxx +++ b/src/tag/TagConfig.cxx @@ -24,12 +24,15 @@ #include "ConfigGlobal.hxx" #include "ConfigOption.hxx" #include "system/FatalError.hxx" +#include "util/Alloc.hxx" #include "util/ASCII.hxx" #include #include +#include + void TagLoadConfig() { @@ -44,7 +47,7 @@ TagLoadConfig() bool quit = false; char *temp, *c, *s; - temp = c = s = g_strdup(value); + temp = c = s = xstrdup(value); do { if (*s == ',' || *s == '\0') { if (*s == '\0') @@ -68,5 +71,5 @@ TagLoadConfig() s++; } while (!quit); - g_free(temp); + free(temp); } diff --git a/src/tag/TagPool.cxx b/src/tag/TagPool.cxx index 189dbdcc4..409edb662 100644 --- a/src/tag/TagPool.cxx +++ b/src/tag/TagPool.cxx @@ -25,6 +25,7 @@ #include #include +#include Mutex tag_pool_lock; diff --git a/src/tag/TagString.cxx b/src/tag/TagString.cxx index 3e8d8c1b0..9d2bd68ec 100644 --- a/src/tag/TagString.cxx +++ b/src/tag/TagString.cxx @@ -19,11 +19,13 @@ #include "config.h" #include "TagString.hxx" +#include "util/Alloc.hxx" #include #include #include +#include /** * Replace invalid sequences with the question mark. @@ -33,7 +35,7 @@ patch_utf8(const char *src, size_t length, const gchar *end) { /* duplicate the string, and replace invalid bytes in that buffer */ - char *dest = g_strdup(src); + char *dest = xstrdup(src); do { dest[end - src] = '?'; @@ -58,9 +60,12 @@ fix_utf8(const char *str, size_t length) /* no, it's not - try to import it from ISO-Latin-1 */ temp = g_convert(str, length, "utf-8", "iso-8859-1", nullptr, &written, nullptr); - if (temp != nullptr) + if (temp != nullptr) { /* success! */ - return temp; + char *p = xstrdup(temp); + g_free(temp); + return p; + } /* no, still broken - there's no medication, just patch invalid sequences */ @@ -96,7 +101,7 @@ clear_non_printable(const char *p, size_t length) if (first == nullptr) return nullptr; - dest = g_strndup(p, length); + dest = xstrndup(p, length); for (size_t i = first - p; i < length; ++i) if (char_is_non_printable(dest[i])) @@ -120,7 +125,7 @@ FixTagString(const char *p, size_t length) if (cleared == nullptr) cleared = utf8; else - g_free(utf8); + free(utf8); return cleared; } diff --git a/src/util/Alloc.cxx b/src/util/Alloc.cxx new file mode 100644 index 000000000..ec3579470 --- /dev/null +++ b/src/util/Alloc.cxx @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2003-2014 The Music Player Daemon Project + * http://www.musicpd.org + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "Alloc.hxx" + +#include +#include +#include + +gcc_noreturn +static void +oom() +{ + (void)write(STDERR_FILENO, "Out of memory\n", 14); + _exit(1); +} + +void * +xalloc(size_t size) +{ + void *p = malloc(size); + if (gcc_unlikely(p == nullptr)) + oom(); + + return p; +} + +void * +xmemdup(const void *s, size_t size) +{ + void *p = xalloc(size); + memcpy(p, s, size); + return p; +} + +char * +xstrdup(const char *s) +{ + char *p = strdup(s); + if (gcc_unlikely(p == nullptr)) + oom(); + + return p; +} + +char * +xstrndup(const char *s, size_t n) +{ +#ifdef WIN32 + char *p = (char *)xalloc(n + 1); + memcpy(p, s, n); + p[n] = 0; +#else + char *p = strndup(s, n); + if (gcc_unlikely(p == nullptr)) + oom(); +#endif + + return p; +} diff --git a/src/util/Alloc.hxx b/src/util/Alloc.hxx new file mode 100644 index 000000000..15c123b7a --- /dev/null +++ b/src/util/Alloc.hxx @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2003-2014 The Music Player Daemon Project + * http://www.musicpd.org + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef MPD_ALLOC_HXX +#define MPD_ALLOC_HXX + +#include "Compiler.h" + +#include + +/** + * Allocate memory. Use free() to free it. + * + * This function never fails; in out-of-memory situations, it aborts + * the process. + */ +gcc_malloc +void * +xalloc(size_t size); + +/** + * Duplicate memory. Use free() to free it. + * + * This function never fails; in out-of-memory situations, it aborts + * the process. + */ +gcc_malloc gcc_nonnull_all +void * +xmemdup(const void *s, size_t size); + +/** + * Duplicate a string. Use free() to free it. + * + * This function never fails; in out-of-memory situations, it aborts + * the process. + */ +gcc_malloc gcc_nonnull_all +char * +xstrdup(const char *s); + +/** + * Duplicate a string. Use free() to free it. + * + * This function never fails; in out-of-memory situations, it aborts + * the process. + */ +gcc_malloc gcc_nonnull_all +char * +xstrndup(const char *s, size_t n); + +#endif diff --git a/src/util/VarSize.hxx b/src/util/VarSize.hxx index b1123b858..04f1bf580 100644 --- a/src/util/VarSize.hxx +++ b/src/util/VarSize.hxx @@ -30,14 +30,13 @@ #ifndef MPD_VAR_SIZE_HXX #define MPD_VAR_SIZE_HXX +#include "Alloc.hxx" #include "Compiler.h" #include #include #include -#include - /** * Allocate and construct a variable-size object. That is useful for * example when you want to store a variable-length string as the last @@ -61,7 +60,7 @@ NewVarSize(size_t declared_tail_size, size_t real_tail_size, Args&&... args) size_t size = sizeof(T) - declared_tail_size + real_tail_size; /* allocate memory */ - T *instance = (T *)g_malloc(size); + T *instance = (T *)xalloc(size); /* call the constructor */ new(instance) T(std::forward(args)...); @@ -78,7 +77,7 @@ DeleteVarSize(T *instance) instance->T::~T(); /* free memory */ - g_free(instance); + free(instance); } #endif -- cgit v1.2.3