[gst-devel] my registry changes

Thomas Vander Stichele thomas at urgent.rug.ac.be
Thu Apr 11 15:16:03 CEST 2002


Here's a diff and two extra source files (to be put in gst) which 
implement my registry handling changes.  It's still a little rough, but 
wingo asked me to send it to the list before committing.

The basic functionality is there and works as described in 
docs/random/thomasvs/registry.

Later on I'll refine to allow the local registry to actually overrule the 
global.

But maybe other ideas will float up as well; for now this solution 
fixes a number of problems we had, like :

* problems doing multiple concurrent installs (see garnome)
* being able to run tests with a different registry
* more things, can't remember ;)

in the patch are also some of the code review comments that still need to 
be committed.

If you care, check it, if not, feel it later on ;) It shouldn't conflict 
much with the way stuff works right now.

Thomas

-- 

The Dave/Dina Project : future TV today ! - http://davedina.apestaart.org/
<-*-                      -*->
I know someday you'll have a beautiful life
I know you'll be a star in someone else's sky
but why oh why oh why
why can't it be mine ?
<-*- thomas at apestaart.org -*->
URGent, the best radio on the Internet - 24/7 ! - http://urgent.rug.ac.be/
-------------- next part --------------
diff -r --exclude='*.sgml' gstreamer/gst/gst.c gstreamer.regmerge/gst/gst.c
43d42
< 
73c72,73
<   ARG_SCHEDULER
---
>   ARG_SCHEDULER,
>   ARG_REGISTRY
90a91
>   {"gst-registry",   NUL, POPT_ARG_STRING|POPT_ARGFLAG_STRIP, NULL, ARG_REGISTRY,   "registry to use" , "REGISTRY"},
341a343
> 
396a399,401
>       break;
>     case ARG_REGISTRY:
>       gst_registry_option_set (arg);
diff -r --exclude='*.sgml' gstreamer/gst/gst.h gstreamer.regmerge/gst/gst.h
54a55
> #include <gst/gstregistry.h>
diff -r --exclude='*.sgml' gstreamer/gst/gstbuffer.c gstreamer.regmerge/gst/gstbuffer.c
442c442,443
<  * Determines whether a gst_buffer_span is free, or requires a memcpy. 
---
>  * Determines whether a gst_buffer_span is free (as in free beer), 
>  * or requires a memcpy. 
diff -r --exclude='*.sgml' gstreamer/gst/gstbuffer.h gstreamer.regmerge/gst/gstbuffer.h
116c116
<   guint16 		flags;
---
>   guint16 		flags; /* boolean properties of buffer */
125,126c125,126
<   gint64 		timestamp;
<   gint64 		maxage;
---
>   gint64 		timestamp; /* nanoseconds since zero */
>   gint64 		maxage;    /* FIXME: not used yet */
135c135
<   /* utility function pointers */
---
>   /* utility function pointers, can override default */
diff -r --exclude='*.sgml' gstreamer/gst/gstcaps.h gstreamer.regmerge/gst/gstcaps.h
47a48,49
> /* CR1: id is an int corresponding to the quark for the mime type because
>  * it's really fast when doing a first-pass check for caps compatibility */
50c52,53
<   guint16 	id;			/* type id (major type) */
---
>   guint16 	id;			/* type id (major type) representing 
> 					   the mime type */
57c60
<   GstCaps 	*next;
---
>   GstCaps 	*next;			/* not with a GList for efficiency */
59a63,64
> /* factory macros which make it easier for plugins to instantiate */
> 
95c100
< GstCaps*	gst_caps_copy_1				(GstCaps *caps);
---
> GstCaps*	gst_caps_copy_first			(GstCaps *caps);
diff -r --exclude='*.sgml' gstreamer/gst/gstobject.c gstreamer.regmerge/gst/gstobject.c
111a112,114
> 
>   /* CR1: we override the signal property so that an object can propagate the
>    * signal to the parent object */
204a208
>  * Use #gst_object_set_parent to have this done for you.
224a229
>  * 
333c338,339
<   g_return_val_if_fail (object != NULL, NULL);
---
>   /* CR1: GLib checks for NULL */
>   //FIXME: _REDUNDANT g_return_val_if_fail (object != NULL, NULL);
506c512
<     list = g_list_next(list);
---
>     list = g_list_next (list);
508c514
<     if (strcmp(GST_OBJECT_NAME(child), name) == 0) 
---
>     if (strcmp (GST_OBJECT_NAME (child), name) == 0) 
617a624,627
> 
> /* CR1: the GObject changing a property emits signals to it's parents
>  * so that the app can connect a listener to the top-level bin */
> 
647c657
<  * the object hierarchy. Usefull for debugging
---
>  * the object hierarchy. Only useful (or used) for debugging
diff -r --exclude='*.sgml' gstreamer/gst/gstobject.h gstreamer.regmerge/gst/gstobject.h
92a93
> /* signal_object is used to signal to the whole class */
126c127
< /* object locking */
---
> /* CR1: object locking - GObject 2.0 doesn't have threadsafe locking */
diff -r --exclude='*.sgml' gstreamer/gst/gstpad.h gstreamer.regmerge/gst/gstpad.h
180a181
>   //CR1: FIXME: regiontype should go away
313a315
> /* CR1: the space after 'a' is necessary because of preprocessing in gcc */
diff -r --exclude='*.sgml' gstreamer/gst/gstplugin.c gstreamer.regmerge/gst/gstplugin.c
30a31
> #include "gstregistry.h"
51a53,54
> /* whether or not the main app will be writing to the registry */
> gboolean _gst_init_registry_write = FALSE;
60d62
< 
66a69,70
>   GstRegistryRead *gst_reg;
>   gchar *gst_registry;
89,90c93,113
<   if (stat (GST_CONFIG_DIR"/reg.xml", &stat_buf) == 0)
<     doc = xmlParseFile (GST_CONFIG_DIR"/reg.xml");
---
>   /* FIXME:
>    * we want to check both the global and the local registry here
>    * at first, we check if there is a local one, and if there is only use
>    * that one.
>    * Later, we would like to read the global one first, then have each
>    * plugin also in the local one override the global one.
>    */
>   
>   gst_reg = gst_registry_read_get ();
>   if (gst_reg->local_reg)
>     gst_registry = gst_reg->local_reg;
>   else
>     gst_registry = gst_reg->global_reg;
>   
>   if (_gst_init_registry_write)
>   {
>     /* delete it before writing */
>     unlink (gst_registry);
>   }
>   if (stat (gst_registry, &stat_buf) == 0)
>     doc = xmlParseFile (gst_registry);
98c121
<       !plugin_times_older_than(get_time(GST_CONFIG_DIR"/reg.xml"))) 
---
>       !plugin_times_older_than(get_time(gst_registry))) 
272c295
<  * Load all plugins in the path.
---
>  * Load all plugins in the path (in the global GList* _gst_plugin_paths).
279a303
>   if (path == NULL) { g_warning ("gst_plugin_load_all: path is NULL !"); }
720a745,746
>  * There is a separate namespace for each plugin feature type.
>  * See #gst_plugin_get_feature_list
875c901
<   GST_INFO (GST_CAT_PLUGIN_LOADING, "added %d features ", featurecount);
---
>   GST_INFO (GST_CAT_PLUGIN_LOADING, " added %d features ", featurecount);
diff -r --exclude='*.sgml' gstreamer/gst/gstthread.c gstreamer.regmerge/gst/gstthread.c
141a142
>   /* CR1: the GstBin code checks these flags */
437c438
<  * while the state is GST_THREAD_STATE_SPINNING
---
>  * while the state is GST_THREAD_STATE_SPINNING.
469a471,472
>   /* CR1: most of this code is handshaking */
>   /* do this while the thread lives */
506c509
<         g_cond_wait (thread->cond,thread->lock);
---
>         g_cond_wait (thread->cond, thread->lock);
571c574
<   /* we need to destroy the scheduler here bacause it has mapped it's
---
>   /* we need to destroy the scheduler here because it has mapped it's
diff -r --exclude='*.sgml' gstreamer/gst/gstthread.h gstreamer.regmerge/gst/gstthread.h
70,71c70,71
<   GMutex *lock;			/* thread lock/condititon pair... */
<   GCond *cond;			/* used to control the thread */
---
>   GMutex *lock;			/* thread lock/condititon pair ... */
>   GCond *cond;			/* .... used to control the thread */
diff -r --exclude='*.sgml' gstreamer/tools/gst-register.c gstreamer.regmerge/tools/gst-register.c
38,51d37
< #define GLOBAL_REGISTRY_DIR      GST_CONFIG_DIR
< #define GLOBAL_REGISTRY_FILE     GLOBAL_REGISTRY_DIR"/reg.xml"
< #define GLOBAL_REGISTRY_FILE_TMP GLOBAL_REGISTRY_DIR"/.reg.xml.tmp"
< 
< #define REGISTRY_DIR_PERMS (S_ISGID | \
< 			    S_IRUSR | S_IWUSR | S_IXUSR | \
< 			    S_IRGRP | S_IXGRP | \
< 			    S_IROTH | S_IXOTH)
< #define REGISTRY_TMPFILE_PERMS (S_IRUSR | S_IWUSR)
< #define REGISTRY_FILE_PERMS (S_IRUSR | S_IWUSR | \
< 			     S_IRGRP | S_IWGRP | \
< 			     S_IROTH | S_IWOTH)
< 
< 
53a40
> extern gboolean _gst_init_registry_write; /* we ask post_init to be delayed */
186a174
>     GstRegistryWrite *gst_reg;
198,202d185
<     /* remove the old registry file first
<        If this fails, we simply ignore it since we'll overwrite it later
<         anyway. */
<     unlink(GLOBAL_REGISTRY_FILE);
< 
206a190
>     _gst_init_registry_write = TRUE; /* signal that we're writing registry */
208a193,201
>     /* remove the old registry file first
>      * if a local is returned, then do that, else remove the global one
>      * If this fails, we simply ignore it since we'll overwrite it later
>      * anyway */
>     gst_reg = gst_registry_write_get ();
>     unlink (gst_reg->file);
> 
>     GST_INFO (GST_CAT_PLUGIN_LOADING, " Writing to registry %s", gst_reg->file);
> 
212,214d204
<     /* Check that directory for config exists */
<     check_dir(GLOBAL_REGISTRY_DIR);
<     
220c210,213
< 
---
>     
>     if (gst_reg->dir)
>       check_dir(gst_reg->dir);
>     
222c215
<     save_registry(GLOBAL_REGISTRY_FILE_TMP, &doc);
---
>     save_registry(gst_reg->tmp_file, &doc);
225,226c218,244
<     move_file(GLOBAL_REGISTRY_FILE_TMP, GLOBAL_REGISTRY_FILE, &newmode);
< 
---
>     move_file(gst_reg->tmp_file, gst_reg->file, &newmode);
> #ifdef THOMAS
>     }
>     else
>     {
>       gchar *homedir;
>       gchar *reg_dir, *reg_file_tmp, *reg_file;
> 
>       homedir = (gchar *) g_get_home_dir ();
>       reg_dir      = g_strjoin ("/", homedir, LOCAL_REGISTRY_DIR,      NULL);
>       reg_file_tmp = g_strjoin ("/", homedir, LOCAL_REGISTRY_FILE_TMP, NULL);
>       reg_file     = g_strjoin ("/", homedir, LOCAL_REGISTRY_FILE,     NULL);
> 
>       /* try to make the dir; we'll find out if it fails anyway */
>       mkdir(reg_dir, S_IRWXU);
>       g_free(reg_dir);
> 
>       /* Save the registry to a tmp file. */
>       save_registry(reg_file_tmp, &doc);
> 
>       /* Make the tmp file live. */
>       move_file(reg_file_tmp, reg_file, &newmode);
>       g_free(reg_file_tmp);
>       g_free(reg_file);
>     }
> #endif
>     g_free (gst_reg);
-------------- next part --------------
/* GStreamer
 * Copyright (C) 1999,2000 Erik Walthinsen <omega at cse.ogi.edu>
 *                    2000 Wim Taymans <wtay at chello.be>
 *
 * gstregistry.c: handle registry
 * 
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library 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
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library 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.
 */

#include <glib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>

#include "gstinfo.h"
#include "gstregistry.h"

static gchar *gst_registry_option = NULL;

/* save the registry specified as an option */
void
gst_registry_option_set (const gchar *registry)
{
  gst_registry_option = g_strdup (registry);
  return;
}

/* decide if we're going to use the global registry or not 
 * - if root, use global
 * - if not root :
 *   - if user can write to global, use global
 *   - else use local
 */
gboolean
gst_registry_use_global (void)
{
  //struct stat reg_stat;
  FILE *reg;
  
  if (getuid () == 0) return TRUE; 	/* root always uses global */

  /* check if we can write to the global registry somehow */
  reg = fopen (GLOBAL_REGISTRY_FILE, "a");
  if (reg == NULL) { return FALSE; }
  else
  {
    /* we can write to it, do so for kicks */
    fclose (reg);
  }
  
  /* we can write to it, so now see if we can write in the dir as well */ 
  if (access (GLOBAL_REGISTRY_DIR, W_OK) == 0) return TRUE;

  return FALSE;
}

/* get the data that tells us where we can write the registry
 * Allocate, fill in the GstRegistryWrite struct according to 
 * current situation, and return it */
GstRegistryWrite *
gst_registry_write_get ()
{
  GstRegistryWrite *gst_reg = g_malloc (sizeof (GstRegistryWrite));
  
  /* if a registry is specified on command line, use that one */
  if (gst_registry_option)
  {
    /* FIXME: maybe parse the dir from file ? */
    gst_reg->dir = NULL;
    gst_reg->file = gst_registry_option;
    /* we cannot use the temp dir since the move needs to be on same device */
    gst_reg->tmp_file = g_strdup_printf ("%s.tmp", gst_registry_option);
  }
  else
  {
    if (gst_registry_use_global ())
    {
      gst_reg->dir      = g_strdup (GLOBAL_REGISTRY_DIR);
      gst_reg->file     = g_strdup (GLOBAL_REGISTRY_FILE);
      gst_reg->tmp_file = g_strdup (GLOBAL_REGISTRY_FILE_TMP);
    }
    else
    {
      gchar *homedir = (gchar *) g_get_home_dir ();
      
      gst_reg->dir = g_strjoin ("/", homedir, LOCAL_REGISTRY_DIR, NULL);
      gst_reg->file = g_strjoin ("/", homedir, LOCAL_REGISTRY_FILE, NULL);
      gst_reg->tmp_file = g_strjoin ("/", homedir, LOCAL_REGISTRY_FILE_TMP, NULL);
    }
  } 
  return gst_reg;
}

/* fill in the GstRegistryRead struct according to current situation */
GstRegistryRead *
gst_registry_read_get ()
{
  GstRegistryRead *gst_reg = g_malloc (sizeof (GstRegistryRead));
  
  /* if a registry is specified on command line, use that one */
  if (gst_registry_option)
  {
    /* FIXME: maybe parse the dir from file ? */
    gst_reg->local_reg = NULL;
    gst_reg->global_reg = gst_registry_option;
  }
  else
  {
    gchar *homedir = (gchar *) g_get_home_dir ();
    gst_reg->local_reg = g_strjoin ("/", homedir, LOCAL_REGISTRY_FILE, NULL);
    gst_reg->global_reg = g_strdup (GLOBAL_REGISTRY_FILE);
  }
  return gst_reg;
}
-------------- next part --------------
/* GStreamer
 * Copyright (C) 1999,2000 Erik Walthinsen <omega at cse.ogi.edu>
 *                    2000 Wim Taymans <wim.taymans at chello.be>
 *
 * gstregistry.h: Header for registry handling
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library 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
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library 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.
 */


#ifndef __GST_REGISTRY_H__
#define __GST_REGISTRY_H__

#define GLOBAL_REGISTRY_DIR      GST_CONFIG_DIR
#define GLOBAL_REGISTRY_FILE     GLOBAL_REGISTRY_DIR"/reg.xml"
#define GLOBAL_REGISTRY_FILE_TMP GLOBAL_REGISTRY_DIR"/.reg.xml.tmp"

#define LOCAL_REGISTRY_DIR       ".gstreamer"
#define LOCAL_REGISTRY_FILE      LOCAL_REGISTRY_DIR"/reg.xml"
#define LOCAL_REGISTRY_FILE_TMP  LOCAL_REGISTRY_DIR"/.reg.xml.tmp"

#define REGISTRY_DIR_PERMS (S_ISGID | \
                            S_IRUSR | S_IWUSR | S_IXUSR | \
		            S_IRGRP | S_IXGRP | \
			    S_IROTH | S_IXOTH)
#define REGISTRY_TMPFILE_PERMS (S_IRUSR | S_IWUSR)
#define REGISTRY_FILE_PERMS (S_IRUSR | S_IWUSR | \
                             S_IRGRP | S_IWGRP | \
			     S_IROTH | S_IWOTH)

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

typedef struct _GstRegistryWrite GstRegistryWrite;
struct _GstRegistryWrite {
  gchar *dir;
  gchar *file;
  gchar *tmp_file;
};

typedef struct _GstRegistryRead GstRegistryRead;
struct _GstRegistryRead {
  gchar *global_reg;
  gchar *local_reg;
};

GstRegistryWrite 	*gst_registry_write_get  	(void);
GstRegistryRead 	*gst_registry_read_get  	(void);
void 			gst_registry_option_set 	(const gchar *registry);
  
#ifdef __cplusplus
}
#endif /* __cplusplus */

#endif /* __GST_REGISTRY_H__ */


More information about the gstreamer-devel mailing list