kernel: Use anonymous namespaces to avoid type collisions.
The anonymous namespace makes type definitions local to the translation unit (like static does for objects). For pretty much any type not shared across multiple files this is what one wants to happen (and might erroneously expect to happen automatically). This commit solves some actual collisions that were present: * The VFS and the rootfs both used an incompatible VnodeHash struct for their BOpenHashTable. * XSI semaphores and message queues both used queued_thread, Ipc and IpcHashTableDefinition. For release builds these did not cause problems as the types were fully inlined. Debug builds would crash at boot however because parts of a BOpenHashTable<VnodeHash> from the rootfs meant to operate on struct rootfs_vnode would be applied to one from the VFS expecting struct vnode. As such collisions are violations of the one definition rule, the code is at fault and unfortunatley the compiler isn't required to diagnose such problems across translation units (which isn't actually trivial). This can lead to subtle and hard to debug problems and it's therefore best to avoid leaking types into the global namespace whenever possible.
This commit is contained in:
@@ -59,6 +59,8 @@
|
||||
void *gDmaAddress;
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
struct memory_type_range : DoublyLinkedListLinkImpl<memory_type_range> {
|
||||
uint64 base;
|
||||
uint64 size;
|
||||
@@ -89,6 +91,9 @@ struct update_mtrr_info {
|
||||
|
||||
typedef DoublyLinkedList<memory_type_range> MemoryTypeRangeList;
|
||||
|
||||
} // namespace
|
||||
|
||||
|
||||
static mutex sMemoryTypeLock = MUTEX_INITIALIZER("memory type ranges");
|
||||
static MemoryTypeRangeList sMemoryTypeRanges;
|
||||
static int32 sMemoryTypeRangeCount = 0;
|
||||
|
||||
+4
@@ -50,6 +50,8 @@ static const bigtime_t kTransactionIdleTime = 2000000LL;
|
||||
// a transaction is considered idle after 2 seconds of inactivity
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
struct cache_transaction;
|
||||
struct cached_block;
|
||||
struct block_cache;
|
||||
@@ -322,6 +324,8 @@ public:
|
||||
|
||||
typedef AutoLocker<block_cache, TransactionLocking> TransactionLocker;
|
||||
|
||||
} // namespace
|
||||
|
||||
|
||||
#if BLOCK_CACHE_BLOCK_TRACING && !defined(BUILDING_USERLAND_FS_SERVER)
|
||||
namespace BlockTracing {
|
||||
|
||||
@@ -50,6 +50,8 @@
|
||||
#endif
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
struct devfs_partition {
|
||||
struct devfs_vnode* raw_device;
|
||||
partition_info info;
|
||||
@@ -158,11 +160,11 @@ enum {
|
||||
ITERATION_STATE_BEGIN = ITERATION_STATE_DOT,
|
||||
};
|
||||
|
||||
// extern and in a private namespace only to make forward declaration possible
|
||||
namespace {
|
||||
extern fs_volume_ops kVolumeOps;
|
||||
extern fs_vnode_ops kVnodeOps;
|
||||
}
|
||||
// extern only to make forward declaration possible
|
||||
extern fs_volume_ops kVolumeOps;
|
||||
extern fs_vnode_ops kVnodeOps;
|
||||
|
||||
} // namespace
|
||||
|
||||
|
||||
static status_t get_node_for_path(struct devfs* fs, const char* path,
|
||||
|
||||
@@ -219,27 +219,6 @@ public:
|
||||
};
|
||||
|
||||
|
||||
} // unnamed namespace
|
||||
|
||||
|
||||
static status_t unload_driver(legacy_driver *driver);
|
||||
static status_t load_driver(legacy_driver *driver);
|
||||
|
||||
|
||||
static DriverWatcher sDriverWatcher;
|
||||
static int32 sDriverEventsPending;
|
||||
static DriverEventList sDriverEvents;
|
||||
static mutex sDriverEventsLock = MUTEX_INITIALIZER("driver events");
|
||||
// inner lock, protects the sDriverEvents list only
|
||||
static DirectoryWatcher sDirectoryWatcher;
|
||||
static DirectoryNodeHash sDirectoryNodeHash;
|
||||
static recursive_lock sLock;
|
||||
static bool sWatching;
|
||||
|
||||
|
||||
// #pragma mark - driver private
|
||||
|
||||
|
||||
struct DriverHash {
|
||||
typedef const char* KeyType;
|
||||
typedef legacy_driver ValueType;
|
||||
@@ -268,9 +247,29 @@ struct DriverHash {
|
||||
typedef BOpenHashTable<DriverHash> DriverTable;
|
||||
|
||||
|
||||
} // unnamed namespace
|
||||
|
||||
|
||||
static status_t unload_driver(legacy_driver *driver);
|
||||
static status_t load_driver(legacy_driver *driver);
|
||||
|
||||
|
||||
static DriverWatcher sDriverWatcher;
|
||||
static int32 sDriverEventsPending;
|
||||
static DriverEventList sDriverEvents;
|
||||
static mutex sDriverEventsLock = MUTEX_INITIALIZER("driver events");
|
||||
// inner lock, protects the sDriverEvents list only
|
||||
static DirectoryWatcher sDirectoryWatcher;
|
||||
static DirectoryNodeHash sDirectoryNodeHash;
|
||||
static recursive_lock sLock;
|
||||
static bool sWatching;
|
||||
|
||||
static DriverTable* sDriverHash;
|
||||
|
||||
|
||||
// #pragma mark - driver private
|
||||
|
||||
|
||||
/*! Collects all published devices of a driver, compares them to what the
|
||||
driver would publish now, and then publishes/unpublishes the devices
|
||||
as needed.
|
||||
|
||||
@@ -53,6 +53,8 @@
|
||||
#endif
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
#define IMAGE_HASH_SIZE 16
|
||||
|
||||
struct ImageHashDefinition {
|
||||
@@ -77,6 +79,9 @@ struct ImageHashDefinition {
|
||||
|
||||
typedef BOpenHashTable<ImageHashDefinition> ImageHash;
|
||||
|
||||
} // namespace
|
||||
|
||||
|
||||
static ImageHash *sImagesHash;
|
||||
|
||||
static struct elf_image_info *sKernelImage = NULL;
|
||||
|
||||
@@ -46,6 +46,8 @@
|
||||
#endif
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
struct rootfs_stream {
|
||||
mode_t type;
|
||||
struct stream_dir {
|
||||
@@ -124,11 +126,13 @@ enum {
|
||||
ITERATION_STATE_BEGIN = ITERATION_STATE_DOT,
|
||||
};
|
||||
|
||||
// extern and in a private namespace only to make forward declaration possible
|
||||
namespace {
|
||||
extern fs_volume_ops sVolumeOps;
|
||||
extern fs_vnode_ops sVnodeOps;
|
||||
}
|
||||
|
||||
// extern only to make forward declaration possible
|
||||
extern fs_volume_ops sVolumeOps;
|
||||
extern fs_vnode_ops sVnodeOps;
|
||||
|
||||
} // namespace
|
||||
|
||||
|
||||
#define ROOTFS_HASH_SIZE 16
|
||||
|
||||
|
||||
@@ -111,11 +111,6 @@ const static size_t kMaxPathLength = 65536;
|
||||
// on PATH_MAX
|
||||
|
||||
|
||||
struct vnode_hash_key {
|
||||
dev_t device;
|
||||
ino_t vnode;
|
||||
};
|
||||
|
||||
typedef DoublyLinkedList<vnode> VnodeList;
|
||||
|
||||
/*! \brief Structure to manage a mounted file system
|
||||
@@ -171,6 +166,9 @@ struct fs_mount {
|
||||
bool owns_file_device;
|
||||
};
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
struct advisory_lock : public DoublyLinkedListLinkImpl<advisory_lock> {
|
||||
list_link link;
|
||||
team_id team;
|
||||
@@ -182,6 +180,9 @@ struct advisory_lock : public DoublyLinkedListLinkImpl<advisory_lock> {
|
||||
|
||||
typedef DoublyLinkedList<advisory_lock> LockList;
|
||||
|
||||
} // namespace
|
||||
|
||||
|
||||
struct advisory_locking {
|
||||
sem_id lock;
|
||||
sem_id wait_sem;
|
||||
@@ -251,6 +252,13 @@ static rw_lock sVnodeLock = RW_LOCK_INITIALIZER("vfs_vnode_lock");
|
||||
static mutex sIOContextRootLock = MUTEX_INITIALIZER("io_context::root lock");
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
struct vnode_hash_key {
|
||||
dev_t device;
|
||||
ino_t vnode;
|
||||
};
|
||||
|
||||
struct VnodeHash {
|
||||
typedef vnode_hash_key KeyType;
|
||||
typedef struct vnode ValueType;
|
||||
@@ -311,6 +319,8 @@ struct MountHash {
|
||||
|
||||
typedef BOpenHashTable<MountHash> MountTable;
|
||||
|
||||
} // namespace
|
||||
|
||||
|
||||
#define VNODE_HASH_TABLE_SIZE 1024
|
||||
static VnodeTable* sVnodeTable;
|
||||
@@ -520,7 +530,8 @@ static struct fd_ops sQueryOps = {
|
||||
};
|
||||
|
||||
|
||||
// VNodePutter
|
||||
namespace {
|
||||
|
||||
class VNodePutter {
|
||||
public:
|
||||
VNodePutter(struct vnode* vnode = NULL) : fVNode(vnode) {}
|
||||
@@ -597,6 +608,8 @@ private:
|
||||
bool fKernel;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
|
||||
#if VFS_PAGES_IO_TRACING
|
||||
|
||||
|
||||
@@ -33,6 +33,8 @@
|
||||
#define ADD_DEBUGGER_COMMANDS
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
struct ImageTableDefinition {
|
||||
typedef image_id KeyType;
|
||||
typedef struct image ValueType;
|
||||
@@ -68,6 +70,8 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
|
||||
static image_id sNextImageID = 1;
|
||||
static mutex sImageMutex = MUTEX_INITIALIZER("image");
|
||||
|
||||
@@ -275,45 +275,6 @@ private:
|
||||
NotificationList fNotifications;
|
||||
};
|
||||
|
||||
} // namespace Module
|
||||
|
||||
using namespace Module;
|
||||
|
||||
/* These are the standard base paths where we start to look for modules
|
||||
* to load. Order is important, the last entry here will be searched
|
||||
* first.
|
||||
*/
|
||||
static const directory_which kModulePaths[] = {
|
||||
B_BEOS_ADDONS_DIRECTORY,
|
||||
B_SYSTEM_NONPACKAGED_ADDONS_DIRECTORY,
|
||||
B_USER_ADDONS_DIRECTORY,
|
||||
B_USER_NONPACKAGED_ADDONS_DIRECTORY,
|
||||
};
|
||||
|
||||
static const uint32 kNumModulePaths = sizeof(kModulePaths)
|
||||
/ sizeof(kModulePaths[0]);
|
||||
static const uint32 kFirstNonSystemModulePath = 1;
|
||||
|
||||
|
||||
static ModuleNotificationService sModuleNotificationService;
|
||||
static bool sDisableUserAddOns = false;
|
||||
|
||||
/* Locking scheme: There is a global lock only; having several locks
|
||||
makes trouble if dependent modules get loaded concurrently ->
|
||||
they have to wait for each other, i.e. we need one lock per module;
|
||||
also we must detect circular references during init and not dead-lock.
|
||||
|
||||
Reference counting: get_module() increments the ref count of a module,
|
||||
put_module() decrements it. When a B_KEEP_LOADED module is initialized
|
||||
the ref count is incremented once more, so it never gets
|
||||
uninitialized/unloaded. A referenced module, unless it's built-in, has a
|
||||
non-null module_image and owns a reference to the image. When the last
|
||||
module reference is put, the image's reference is released and module_image
|
||||
zeroed (as long as the boot volume has not been mounted, it is not zeroed).
|
||||
An unreferenced module image is unloaded (when the boot volume is mounted).
|
||||
*/
|
||||
static recursive_lock sModulesLock;
|
||||
|
||||
|
||||
struct ModuleHash {
|
||||
typedef const char* KeyType;
|
||||
@@ -364,6 +325,45 @@ struct ImageHash {
|
||||
|
||||
typedef BOpenHashTable<ImageHash> ImageTable;
|
||||
|
||||
} // namespace Module
|
||||
|
||||
using namespace Module;
|
||||
|
||||
/* These are the standard base paths where we start to look for modules
|
||||
* to load. Order is important, the last entry here will be searched
|
||||
* first.
|
||||
*/
|
||||
static const directory_which kModulePaths[] = {
|
||||
B_BEOS_ADDONS_DIRECTORY,
|
||||
B_SYSTEM_NONPACKAGED_ADDONS_DIRECTORY,
|
||||
B_USER_ADDONS_DIRECTORY,
|
||||
B_USER_NONPACKAGED_ADDONS_DIRECTORY,
|
||||
};
|
||||
|
||||
static const uint32 kNumModulePaths = sizeof(kModulePaths)
|
||||
/ sizeof(kModulePaths[0]);
|
||||
static const uint32 kFirstNonSystemModulePath = 1;
|
||||
|
||||
|
||||
static ModuleNotificationService sModuleNotificationService;
|
||||
static bool sDisableUserAddOns = false;
|
||||
|
||||
/* Locking scheme: There is a global lock only; having several locks
|
||||
makes trouble if dependent modules get loaded concurrently ->
|
||||
they have to wait for each other, i.e. we need one lock per module;
|
||||
also we must detect circular references during init and not dead-lock.
|
||||
|
||||
Reference counting: get_module() increments the ref count of a module,
|
||||
put_module() decrements it. When a B_KEEP_LOADED module is initialized
|
||||
the ref count is incremented once more, so it never gets
|
||||
uninitialized/unloaded. A referenced module, unless it's built-in, has a
|
||||
non-null module_image and owns a reference to the image. When the last
|
||||
module reference is put, the image's reference is released and module_image
|
||||
zeroed (as long as the boot volume has not been mounted, it is not zeroed).
|
||||
An unreferenced module image is unloaded (when the boot volume is mounted).
|
||||
*/
|
||||
static recursive_lock sModulesLock;
|
||||
|
||||
|
||||
/* We store the loaded modules by directory path, and all known modules
|
||||
* by module name in a hash table for quick access
|
||||
|
||||
@@ -86,11 +86,7 @@
|
||||
// has a reference to a deleted port.
|
||||
|
||||
|
||||
struct port_message;
|
||||
|
||||
|
||||
static void put_port_message(port_message* message);
|
||||
|
||||
namespace {
|
||||
|
||||
struct port_message : DoublyLinkedListLinkImpl<port_message> {
|
||||
int32 code;
|
||||
@@ -103,6 +99,13 @@ struct port_message : DoublyLinkedListLinkImpl<port_message> {
|
||||
|
||||
typedef DoublyLinkedList<port_message> MessageList;
|
||||
|
||||
} // namespace
|
||||
|
||||
|
||||
static void put_port_message(port_message* message);
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
struct Port : public KernelReferenceable {
|
||||
enum State {
|
||||
@@ -233,6 +236,8 @@ public:
|
||||
void Notify(uint32 opcode, port_id team);
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
|
||||
// #pragma mark - tracing
|
||||
|
||||
|
||||
@@ -24,6 +24,8 @@
|
||||
#include <util/StringHash.h>
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
class SemInfo {
|
||||
public:
|
||||
SemInfo()
|
||||
@@ -364,6 +366,8 @@ struct TeamSemHashDefinition {
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
|
||||
struct realtime_sem_context {
|
||||
realtime_sem_context()
|
||||
|
||||
@@ -33,6 +33,9 @@
|
||||
# define TRACE_ERROR(x) dprintf x
|
||||
#endif
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
// Queue for holding blocked threads
|
||||
struct queued_thread : DoublyLinkedListLinkImpl<queued_thread> {
|
||||
queued_thread(Thread *_thread, int32 _message_length)
|
||||
@@ -374,6 +377,9 @@ struct IpcHashTableDefinition {
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
|
||||
// Arbitrary limits
|
||||
#define MAX_XSI_MESSAGE 4096
|
||||
#define MAX_XSI_MESSAGE_QUEUE 1024
|
||||
|
||||
@@ -34,6 +34,9 @@
|
||||
# define TRACE_ERROR(x) dprintf x
|
||||
#endif
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
// Queue for holding blocked threads
|
||||
struct queued_thread : DoublyLinkedListLinkImpl<queued_thread> {
|
||||
queued_thread(Thread *thread, int32 count)
|
||||
@@ -72,6 +75,10 @@ typedef DoublyLinkedList<sem_undo> UndoList;
|
||||
typedef DoublyLinkedList<sem_undo,
|
||||
DoublyLinkedListMemberGetLink<sem_undo, &sem_undo::team_link> > TeamList;
|
||||
|
||||
} // namespace
|
||||
|
||||
|
||||
// Forward declared in global namespace.
|
||||
struct xsi_sem_context {
|
||||
xsi_sem_context()
|
||||
{
|
||||
@@ -87,6 +94,9 @@ struct xsi_sem_context {
|
||||
mutex lock;
|
||||
};
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
// Xsi semaphore definition
|
||||
class XsiSemaphore {
|
||||
public:
|
||||
@@ -621,6 +631,9 @@ struct IpcHashTableDefinition {
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
|
||||
// Arbitrary limit
|
||||
#define MAX_XSI_SEMAPHORE 4096
|
||||
#define MAX_XSI_SEMAPHORE_SET 2048
|
||||
|
||||
@@ -42,6 +42,8 @@
|
||||
// #pragma mark - AddressSpaceHashDefinition
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
struct AddressSpaceHashDefinition {
|
||||
typedef team_id KeyType;
|
||||
typedef VMAddressSpace ValueType;
|
||||
@@ -69,6 +71,9 @@ struct AddressSpaceHashDefinition {
|
||||
|
||||
typedef BOpenHashTable<AddressSpaceHashDefinition> AddressSpaceTable;
|
||||
|
||||
} // namespace
|
||||
|
||||
|
||||
static AddressSpaceTable sAddressSpaceTable;
|
||||
static rw_lock sAddressSpaceTableLock;
|
||||
|
||||
|
||||
@@ -73,6 +73,8 @@
|
||||
#endif
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
class AreaCacheLocking {
|
||||
public:
|
||||
inline bool Lock(VMCache* lockable)
|
||||
@@ -229,6 +231,8 @@ private:
|
||||
VMCache* fBottomCache;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
|
||||
// The memory reserve an allocation of the certain priority must not touch.
|
||||
static const size_t kMemoryReserveForPriority[] = {
|
||||
|
||||
Reference in New Issue
Block a user