You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucy.apache.org by ma...@apache.org on 2010/01/04 23:09:51 UTC
svn commit: r895800 - in /lucene/lucy/trunk/core/Lucy/Object: VTable.bp
VTable.c
Author: marvin
Date: Mon Jan 4 22:09:50 2010
New Revision: 895800
URL: http://svn.apache.org/viewvc?rev=895800&view=rev
Log:
Switch VTable_registry over from Hash to LockFreeRegistry.
Modified:
lucene/lucy/trunk/core/Lucy/Object/VTable.bp
lucene/lucy/trunk/core/Lucy/Object/VTable.c
Modified: lucene/lucy/trunk/core/Lucy/Object/VTable.bp
URL: http://svn.apache.org/viewvc/lucene/lucy/trunk/core/Lucy/Object/VTable.bp?rev=895800&r1=895799&r2=895800&view=diff
==============================================================================
--- lucene/lucy/trunk/core/Lucy/Object/VTable.bp (original)
+++ lucene/lucy/trunk/core/Lucy/Object/VTable.bp Mon Jan 4 22:09:50 2010
@@ -18,7 +18,7 @@
Callback **callbacks;
lucy_method_t[1] methods; /* flexible array */
- inert Hash *registry;
+ inert LockFreeRegistry *registry;
/** Return a singleton. If a VTable can be found in the registry based on
* the subclass name, it will be returned. Otherwise, a new VTable will
@@ -34,11 +34,13 @@
/** Register a vtable, so that it can be retrieved by class name.
*
* TODO: Move this functionality to some kind of class loader.
+ *
+ * @return true on success, false if the class was already registered.
*/
- inert void
+ inert bool_t
add_to_registry(VTable *vtable);
- /** Initialize the registry hash.
+ /** Initialize the registry.
*/
inert void
init_registry();
Modified: lucene/lucy/trunk/core/Lucy/Object/VTable.c
URL: http://svn.apache.org/viewvc/lucene/lucy/trunk/core/Lucy/Object/VTable.c?rev=895800&r1=895799&r2=895800&view=diff
==============================================================================
--- lucene/lucy/trunk/core/Lucy/Object/VTable.c (original)
+++ lucene/lucy/trunk/core/Lucy/Object/VTable.c Mon Jan 4 22:09:50 2010
@@ -11,8 +11,10 @@
#include "Lucy/Object/CharBuf.h"
#include "Lucy/Object/Err.h"
#include "Lucy/Object/Hash.h"
+#include "Lucy/Object/LockFreeRegistry.h"
#include "Lucy/Object/Undefined.h"
#include "Lucy/Object/VArray.h"
+#include "Lucy/Util/Atomic.h"
#include "Lucy/Util/Memory.h"
size_t lucy_VTable_offset_of_parent = offsetof(lucy_VTable, parent);
@@ -21,7 +23,7 @@
static void
S_scrunch_charbuf(CharBuf *source, CharBuf *target);
-Hash *VTable_registry = NULL;
+LockFreeRegistry *VTable_registry = NULL;
void
VTable_destroy(VTable *self)
@@ -90,19 +92,23 @@
void
VTable_init_registry()
{
- VTable_registry = Hash_new(0);
+ LockFreeRegistry *reg = LFReg_new(256);
+ if (Atomic_cas_ptr((void*volatile*)&VTable_registry, NULL, reg)) {
+ return;
+ }
+ else {
+ DECREF(reg);
+ }
}
VTable*
VTable_singleton(const CharBuf *subclass_name, VTable *parent)
{
- VTable *singleton;
-
- if (VTable_registry == NULL)
- VTable_init_registry();
-
- singleton = (VTable*)Hash_Fetch(VTable_registry, (Obj*)subclass_name);
+ if (VTable_registry == NULL) {
+ VTable_init_registry();
+ }
+ VTable *singleton = (VTable*)LFReg_Fetch(VTable_registry, (Obj*)subclass_name);
if (singleton == NULL) {
VArray *novel_host_methods;
u32_t num_novel;
@@ -155,8 +161,18 @@
DECREF(novel_host_methods);
/* Register the new class, both locally and with host. */
- Hash_Store(VTable_registry, (Obj*)subclass_name, (Obj*)singleton);
- VTable_register_with_host(singleton, parent);
+ if (VTable_add_to_registry(singleton)) {
+ /* Doing this after registering is racy, but hard to fix. :( */
+ VTable_register_with_host(singleton, parent);
+ }
+ else {
+ DECREF(singleton);
+ singleton = (VTable*)LFReg_Fetch(VTable_registry, (Obj*)subclass_name);
+ if (!singleton) {
+ THROW(ERR, "Failed to either insert or fetch VTable for '%o'",
+ subclass_name);
+ }
+ }
}
return singleton;
@@ -197,21 +213,24 @@
}
}
-void
+bool_t
VTable_add_to_registry(VTable *vtable)
{
- VTable *fetched;
-
- if (VTable_registry == NULL)
+ if (VTable_registry == NULL) {
VTable_init_registry();
- fetched = (VTable*)Hash_Fetch(VTable_registry, (Obj*)vtable->name);
- if (fetched) {
- if (fetched != vtable) {
- THROW(ERR, "Attempt to redefine a vtable for '%o'", vtable->name);
- }
+ }
+ if (LFReg_Fetch(VTable_registry, (Obj*)vtable->name)) {
+ return false;
}
else {
- Hash_Store(VTable_registry, (Obj*)vtable->name, (Obj*)vtable);
+ CharBuf *klass = CB_Clone(vtable->name);
+ if (LFReg_Register(VTable_registry, (Obj*)klass, (Obj*)vtable)) {
+ return true;
+ }
+ else {
+ DECREF(klass);
+ return false;
+ }
}
}
@@ -220,7 +239,7 @@
{
VTable *vtable = NULL;
if (VTable_registry != NULL) {
- vtable = (VTable*)Hash_Fetch(VTable_registry, (Obj*)class_name);
+ vtable = (VTable*)LFReg_Fetch(VTable_registry, (Obj*)class_name);
}
return vtable;
}