* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
*
* Author: Sam Thursfield <ssssam@gmail.com>
*/
#include "gsettingsbackend.h"
#include "giomodule.h"
-
-#define _WIN32_WINNT 0x0500
-#define WIN32_LEAN_AND_MEAN
#include <windows.h>
//#define TRACE
gchar *path_name, *c;
/* All key paths are treated as absolute; gsettings doesn't seem to enforce a
- * preceeding /.
+ * preceding /.
*/
if (key_name[0] == '/')
key_name ++;
}
}
-
+#if 0
static void
registry_cache_dump (GNode *cache_node,
gpointer data)
g_node_children_foreach (cache_node, G_TRAVERSE_ALL, registry_cache_dump,
GINT_TO_POINTER (new_depth));
}
-
+#endif
typedef struct
{
RegistryCacheItem *item;
gchar *component = key_name,
*c = strchr (component, '/');
+ GNode *child;
if (c != NULL)
*c = 0;
if (item->subscription_count > 0)
n_parent_watches ++;
- GNode *child = registry_cache_find_immediate_child (node, component);
+ child = registry_cache_find_immediate_child (node, component);
if (child == NULL && create_if_not_found)
{
item = g_slice_new (RegistryCacheItem);
if (key_name[0] == '/')
key_name ++;
- /* Ignore preceeding / */
+ /* Ignore preceding / */
component = g_strdup (key_name);
c = strchr (component, '/');
if (c != NULL)
GNode *node;
gboolean changed;
+ const gchar *type_string = g_variant_get_type_string (variant);
+
action = user_data;
self = G_REGISTRY_BACKEND (action->self);
hroot = action->hroot;
value.type = REG_NONE;
value.ptr = NULL;
- const gchar *type_string = g_variant_get_type_string (variant);
switch (type_string[0])
{
case 'b': case 'y': case 'n': case 'q': case 'i': case 'u':
result = RegSetValueExA (hpath, value_name, 0, value.type, value_data, value_data_size);
if (result != ERROR_SUCCESS)
- g_message_win32_error (result, "gregistrybackend: setting value %s\%s\\%s failed.\n",
+ g_message_win32_error (result, "gregistrybackend: setting value %s\\%s\\%s failed.\n",
self->base_path, path_name, value_name);
/* If the write fails then it will seem like the value has changed until the
GRegistryBackend *self = G_REGISTRY_BACKEND (backend);
LONG result;
HKEY hroot;
+ RegistryWrite action;
result = RegCreateKeyExA (HKEY_CURRENT_USER, self->base_path, 0, NULL, 0,
KEY_WRITE, NULL, &hroot, NULL);
return FALSE;
}
- RegistryWrite action = { self, hroot };
+ action.self = self;
+ action.hroot = hroot;
g_registry_backend_write_one (key_name, value, &action);
g_settings_backend_changed (backend, key_name, origin_tag);
GRegistryBackend *self = G_REGISTRY_BACKEND (backend);
LONG result;
HKEY hroot;
+ RegistryWrite action;
result = RegCreateKeyExA (HKEY_CURRENT_USER, self->base_path, 0, NULL, 0,
KEY_WRITE, NULL, &hroot, NULL);
return FALSE;
}
- RegistryWrite action = { self, hroot };
+ action.self = self;
+ action.hroot = hroot;
g_tree_foreach (values, (GTraverseFunc)g_registry_backend_write_one,
&action);
if (item->subscription_count > 0)
{
+ gint i;
/* There must be some watches active if this node is a watch point */
g_warn_if_fail (self->cache_nodes->len > 1);
/* This is a watch point that has been deleted. Let's free the watch! */
- gint i;
for (i=1; i<self->cache_nodes->len; i++)
if (g_ptr_array_index (self->cache_nodes, i) == node)
break;
g_object_unref (event->self);
g_slice_free (RegistryEvent, event);
- return FALSE;
+ return G_SOURCE_REMOVE;
};
g_return_val_if_fail (self->watch == NULL, FALSE);
- self->cache_lock = g_slice_new (CRITICAL_SECTION);
- InitializeCriticalSection (self->cache_lock);
-
watch = g_slice_new (WatchThreadState);
watch->owner = G_SETTINGS_BACKEND (self);
return TRUE;
fail_2:
- DeleteCriticalSection (self->cache_lock);
- g_slice_free (CRITICAL_SECTION, self->cache_lock);
DeleteCriticalSection (watch->message_lock);
g_slice_free (CRITICAL_SECTION, watch->message_lock);
CloseHandle (watch->message_sent_event);
LeaveCriticalSection (watch->message_lock);
DeleteCriticalSection (watch->message_lock);
- DeleteCriticalSection (self->cache_lock);
g_slice_free (CRITICAL_SECTION, watch->message_lock);
- g_slice_free (CRITICAL_SECTION, self->cache_lock);
CloseHandle (watch->message_sent_event);
CloseHandle (watch->message_received_event);
CloseHandle (watch->thread);
WatchThreadState *watch = self->watch;
GNode *cache_node;
RegistryCacheItem *cache_item;
+#ifdef TRACE
DWORD result;
+#endif
g_return_val_if_fail (watch != NULL, FALSE);
trace ("watch_add_notify: prefix %s.\n", gsettings_prefix);
EnterCriticalSection (self->cache_lock);
cache_node = registry_cache_get_node_for_key (self->cache_root, gsettings_prefix, TRUE);
- g_return_val_if_fail (cache_node != NULL, FALSE);
- g_return_val_if_fail (cache_node->data != NULL, FALSE);
+ if (cache_node == NULL || cache_node->data == NULL)
+ {
+ LeaveCriticalSection (self->cache_lock);
+ g_warn_if_reached ();
+ return FALSE;
+ }
cache_item = cache_node->data;
{
trace ("watch_add_notify: prefix %s already watched, %i subscribers.\n",
gsettings_prefix, cache_item->subscription_count);
+ LeaveCriticalSection (self->cache_lock);
return FALSE;
}
* one was received. If it takes > 200ms there is a possible race but the worst outcome is
* a notification is ignored.
*/
- result = WaitForSingleObject (watch->message_received_event, 200);
- #ifdef TRACE
- if (result != WAIT_OBJECT_0)
- trace ("watch thread is slow to respond - notification may not be added.");
- #endif
+#ifdef TRACE
+ result =
+#endif
+ WaitForSingleObject (watch->message_received_event, 200);
+#ifdef TRACE
+ if (result != WAIT_OBJECT_0)
+ trace ("watch thread is slow to respond - notification may not be added.");
+#endif
+
LeaveCriticalSection (watch->message_lock);
return TRUE;
* Object management junk
********************************************************************************/
-GSettingsBackend *
-g_registry_backend_new (void) {
- return g_object_new (G_TYPE_REGISTRY_BACKEND, NULL);
-}
-
static void
g_registry_backend_finalize (GObject *object)
{
watch_stop_unlocked (self);
}
+ DeleteCriticalSection (self->cache_lock);
+ g_slice_free (CRITICAL_SECTION, self->cache_lock);
+
g_free (self->base_path);
}
static void
g_registry_backend_init (GRegistryBackend *self)
{
+ RegistryCacheItem *item;
self->base_path = g_strdup_printf ("Software\\GSettings");
- RegistryCacheItem *item = g_slice_new (RegistryCacheItem);
+ item = g_slice_new (RegistryCacheItem);
item->value.type = REG_NONE;
item->value.ptr = NULL;
item->name = g_strdup ("<root>");
item->ref_count = 1;
self->cache_root = g_node_new (item);
+ self->cache_lock = g_slice_new (CRITICAL_SECTION);
+ InitializeCriticalSection (self->cache_lock);
+
self->watch = NULL;
}