Improve protocol table locking.

Remove the protocol table from the global lock and make sure that we do
acquire it when accessing the table.
main
David Chisnall 8 years ago
parent b9b6198520
commit bc726e7564

@ -29,10 +29,12 @@ static int protocol_hash(const struct objc_protocol *protocol)
#include "hash_table.h" #include "hash_table.h"
static protocol_table *known_protocol_table; static protocol_table *known_protocol_table;
mutex_t protocol_table_lock;
void init_protocol_table(void) void init_protocol_table(void)
{ {
protocol_initialize(&known_protocol_table, 128); protocol_initialize(&known_protocol_table, 128);
INIT_LOCK(protocol_table_lock);
} }
static void protocol_table_insert(const struct objc_protocol *protocol) static void protocol_table_insert(const struct objc_protocol *protocol)
@ -252,6 +254,7 @@ static BOOL init_protocols(struct objc_protocol_list *protocols)
PRIVATE void objc_init_protocols(struct objc_protocol_list *protocols) PRIVATE void objc_init_protocols(struct objc_protocol_list *protocols)
{ {
LOCK_FOR_SCOPE(&protocol_table_lock);
if (!init_protocols(protocols)) if (!init_protocols(protocols))
{ {
set_buffered_object_at_index(protocols, buffered_objects++); set_buffered_object_at_index(protocols, buffered_objects++);
@ -276,6 +279,7 @@ PRIVATE void objc_init_protocols(struct objc_protocol_list *protocols)
Protocol *objc_getProtocol(const char *name) Protocol *objc_getProtocol(const char *name)
{ {
if (NULL == name) { return NULL; } if (NULL == name) { return NULL; }
LOCK_FOR_SCOPE(&protocol_table_lock);
return (Protocol*)protocol_for_name(name); return (Protocol*)protocol_for_name(name);
} }
@ -557,6 +561,7 @@ BOOL protocol_isEqual(Protocol *p, Protocol *other)
Protocol*__unsafe_unretained* objc_copyProtocolList(unsigned int *outCount) Protocol*__unsafe_unretained* objc_copyProtocolList(unsigned int *outCount)
{ {
LOCK_FOR_SCOPE(&protocol_table_lock);
unsigned int total = known_protocol_table->table_used; unsigned int total = known_protocol_table->table_used;
Protocol **p = calloc(sizeof(Protocol*), known_protocol_table->table_used); Protocol **p = calloc(sizeof(Protocol*), known_protocol_table->table_used);
@ -588,7 +593,7 @@ Protocol *objc_allocateProtocol(const char *name)
void objc_registerProtocol(Protocol *proto) void objc_registerProtocol(Protocol *proto)
{ {
if (NULL == proto) { return; } if (NULL == proto) { return; }
LOCK_RUNTIME_FOR_SCOPE(); LOCK_FOR_SCOPE(&protocol_table_lock);
if (objc_getProtocol(proto->name) != NULL) { return; } if (objc_getProtocol(proto->name) != NULL) { return; }
if (incompleteProtocolClass() != proto->isa) { return; } if (incompleteProtocolClass() != proto->isa) { return; }
init_protocol_classes(); init_protocol_classes();
@ -598,9 +603,12 @@ void objc_registerProtocol(Protocol *proto)
PRIVATE void registerProtocol(Protocol *proto) PRIVATE void registerProtocol(Protocol *proto)
{ {
init_protocol_classes(); init_protocol_classes();
LOCK_RUNTIME_FOR_SCOPE(); LOCK_FOR_SCOPE(&protocol_table_lock);
proto->isa = protocol_class_gsv2; proto->isa = protocol_class_gsv2;
protocol_table_insert(proto); if (protocol_for_name(proto->name) == NULL)
{
protocol_table_insert(proto);
}
} }
void protocol_addMethodDescription(Protocol *aProtocol, void protocol_addMethodDescription(Protocol *aProtocol,
SEL name, SEL name,

Loading…
Cancel
Save