From bd9cd130581019c689060e8d65afcbd3414f6c19 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Thu, 10 Mar 2005 12:53:16 +0000 Subject: [PATCH] Doc updates, Original commit message from CVS: * REQUIREMENTS: * docs/design/part-MT-refcounting.txt: * docs/design/part-clocks.txt: * docs/design/part-conventions.txt: * docs/design/part-gstobject.txt: * docs/design/part-relations.txt: * docs/design/part-standards.txt: * libs/gst/control/dparam.c: (gst_dparam_attach): * libs/gst/control/dparam.h: * libs/gst/control/dparammanager.c: (gst_dpman_add_required_dparam_callback), (gst_dpman_add_required_dparam_direct), (gst_dpman_add_required_dparam_array), (gst_dpman_attach_dparam), (gst_dpman_get_dparam), (gst_dpman_get_dparam_type), (gst_dpman_get_manager), (gst_dpman_bypass_dparam), (gst_dpman_preprocess_asynchronous), (gst_dpman_process_asynchronous), (gst_dpman_process_noop): * libs/gst/control/dparammanager.h: * testsuite/clock/clock2.c: (gst_clock_debug), (element_wait), (main): * testsuite/threads/signals.c: (run_thread), (main): * testsuite/threads/thread.c: (main): * tools/gst-launch.c: (fault_handler_sighandler), (fault_handler_sigaction), (fault_spin): Doc updates, Head backporting. Fix some testcases. --- ChangeLog | 30 ++++++++++++++++ REQUIREMENTS | 2 +- docs/design/part-MT-refcounting.txt | 34 ++++++++++++++++-- docs/design/part-clocks.txt | 8 +++-- docs/design/part-conventions.txt | 2 -- docs/design/part-gstobject.txt | 51 ++++++++++++++++++++++----- docs/design/part-relations.txt | 4 +++ docs/design/part-standards.txt | 46 ++++++++++++++++++------ libs/gst/control/dparam.c | 34 +++++++++++++++--- libs/gst/control/dparam.h | 1 - libs/gst/control/dparammanager.c | 49 ++++++++++++++++++------- libs/gst/control/dparammanager.h | 3 ++ tests/old/testsuite/clock/clock2.c | 3 +- tests/old/testsuite/threads/signals.c | 6 ++-- tests/old/testsuite/threads/thread.c | 1 + testsuite/clock/clock2.c | 3 +- testsuite/threads/signals.c | 6 ++-- testsuite/threads/thread.c | 1 + tools/gst-launch.c | 22 +++++++----- 19 files changed, 244 insertions(+), 62 deletions(-) diff --git a/ChangeLog b/ChangeLog index 9110f6399d..278d1f2abd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,33 @@ +2005-03-10 Wim Taymans + + * REQUIREMENTS: + * docs/design/part-MT-refcounting.txt: + * docs/design/part-clocks.txt: + * docs/design/part-conventions.txt: + * docs/design/part-gstobject.txt: + * docs/design/part-relations.txt: + * docs/design/part-standards.txt: + * libs/gst/control/dparam.c: (gst_dparam_attach): + * libs/gst/control/dparam.h: + * libs/gst/control/dparammanager.c: + (gst_dpman_add_required_dparam_callback), + (gst_dpman_add_required_dparam_direct), + (gst_dpman_add_required_dparam_array), (gst_dpman_attach_dparam), + (gst_dpman_get_dparam), (gst_dpman_get_dparam_type), + (gst_dpman_get_manager), (gst_dpman_bypass_dparam), + (gst_dpman_preprocess_asynchronous), + (gst_dpman_process_asynchronous), (gst_dpman_process_noop): + * libs/gst/control/dparammanager.h: + * testsuite/clock/clock2.c: (gst_clock_debug), (element_wait), + (main): + * testsuite/threads/signals.c: (run_thread), (main): + * testsuite/threads/thread.c: (main): + * tools/gst-launch.c: (fault_handler_sighandler), + (fault_handler_sigaction), (fault_spin): + Doc updates, + Head backporting. + Fix some testcases. + 2005-03-09 Wim Taymans * gst/gstpad.c: (gst_pad_get_direction): diff --git a/REQUIREMENTS b/REQUIREMENTS index f41fb857e0..938ef9de83 100644 --- a/REQUIREMENTS +++ b/REQUIREMENTS @@ -8,7 +8,7 @@ report at http://sourceforge.net/bugs/?group_id=1936. Required libraries: =================== -the latest glib2, currently at v2.0.4 +glib2 libxml2 (also called gnome-xml, available from http://xmlsoft.org/) These libraries are all central parts of gnome, and are available from the diff --git a/docs/design/part-MT-refcounting.txt b/docs/design/part-MT-refcounting.txt index d2313df01a..27654dc454 100644 --- a/docs/design/part-MT-refcounting.txt +++ b/docs/design/part-MT-refcounting.txt @@ -123,6 +123,15 @@ Atomic operations Atomic operations are generally used for refcounting and for the allocation of small fixed size objects in a memchunk. They can also be used to implement a lockfree list or stack. + +Compare and swap + + As part of the atomic operations, compare-and-swap (CAS) can be used to access + or update a single property or pointer in an object without having to take a + lock. + + This technique is currently not used in GStreamer but might be added in the + future in performance critical places. Objects @@ -198,7 +207,8 @@ Objects corresponding macros. The public object properties are marked in the .h files with /*< public >*/. The public properties that require a lock to be held are marked with /*< public >*/ /* with */, where can be - "LOCK" or "STATE_LOCK" to mark the type(s) of lock to be held. + "LOCK" or "STATE_LOCK" or any other lock to mark the type(s) of lock to be + held. Example: @@ -225,7 +235,7 @@ Objects * Property lifetime All properties requiring a lock can change after releasing the associated - lock. This means that as soon as long as you hold the lock, the state of the + lock. This means that as long as you hold the lock, the state of the object regarding the locked properties is consistent with the information obtained. As soon as the lock is released, any values required from the properties might not be valid anymore and can as best be described as a @@ -259,6 +269,16 @@ Objects anymore of the pad. If you need to be sure it is, you need to extend the critical section to include the operations on the peer. + The following code is equivalent to the above but with using the functions + to access object properties. + + peer = gst_pad_get_parent (pad); + if (peer) { + ... use peer ... + + gst_object_unref (GST_OBJECT (peer)); + } + Example: Accessing the name of an object makes a copy of the name. The caller of the @@ -270,6 +290,14 @@ Objects ... use name ... g_free (name); + + or: + + name = gst_object_get_name (object); + + ... use name ... + + g_free (name); * Accessor methods @@ -349,7 +377,7 @@ Objects * GstIterator GstIterator provides an easier way of retrieving elements in a concurrent - list. The followgin code example is equivalent to the previous example. + list. The following code example is equivalent to the previous example. Example: diff --git a/docs/design/part-clocks.txt b/docs/design/part-clocks.txt index 0a3c0bc7f1..feb23f8ea1 100644 --- a/docs/design/part-clocks.txt +++ b/docs/design/part-clocks.txt @@ -30,7 +30,10 @@ is defined as follows: - In PLAYING, the stream time is the delta between the absolute time and the base time. The base time is defined as the absolute time minus the stream time at the time when the pipeline is set to PLAYING. - - after a seek, the stream time is set to 0 again. + - after a seek, the stream time is set to seek time. + +The stream time is completely managed by the GstPipeline object using the +GstClock absolute time. Timestamps @@ -79,7 +82,8 @@ threads. However, registering the same ID for multiple async notifications is not possible, the callback will only be called once. None of the wait operations unref the GstClockID, the application is -responsible for unreffing the ids itself. +responsible for unreffing the ids itself. This holds for both periodic and +single shot notifications. These clock operations do not operate on the stream time, so the callbacks will also occur when not in PLAYING state as if the clock just keeps on diff --git a/docs/design/part-conventions.txt b/docs/design/part-conventions.txt index f2610a7278..5569644d6c 100644 --- a/docs/design/part-conventions.txt +++ b/docs/design/part-conventions.txt @@ -30,8 +30,6 @@ ASYNC. Where there is a prefix, as in the element flags, this is usually droppe element flags should be cross-checked with the header, as there are currently two conventions in use: with and without _FLAGS_ in the middle. -FIXME: check flags for consistency. - Drawing conventions =================== diff --git a/docs/design/part-gstobject.txt b/docs/design/part-gstobject.txt index a85480e21c..093f2f58d3 100644 --- a/docs/design/part-gstobject.txt +++ b/docs/design/part-gstobject.txt @@ -18,13 +18,15 @@ allows for new additions later. GstElement (inside a bin) GstPad (inside an element) + Refcounting ----------- -- GObject refcount is not threadsafe. - GStreamer sets it to a constant value on each _ref/_unref() +- GObject refcount is not threadsafe. This will be changed in the future. + GStreamer for now sets it to a constant value on each _ref/_unref() and uses an atomic int "refcount" instead for threadsafe refcounting This implies you should always use gst_object_ref() and gst_object_unref() ! + Naming ------ - names of objects cannot be changed when they are parented @@ -40,6 +42,7 @@ Naming a more identifiable name. Typically a parent will call _set_name_prefix on children, taking a lock on them to do so. + Locking ------- @@ -47,26 +50,58 @@ The GstObject contains the necessary primitives to lock the object in a thread-safe manner. This will be used to provide general thread-safety as needed. However, this lock is generic, i.e. it covers the whole object. +The object LOCK is a very lowlevel lock that should only be held to access +the object properties for short periods of code. + All members of the GstObject structure marked as /*< public >*/ /* with LOCK */ are protected by this lock. These members can only be accessed for reading -or writing while the lock is held. +or writing while the lock is held. All members should be copied or reffed +if they are used after releasing the LOCK. Note that this does *not* mean that no other thread can modify the object at the same time that the lock is held. It only means that any two sections of code that obey the lock are guaranteed to not be running simultaneously. "The lock is voluntary and cooperative". -This lock will ideally be used for parentage and refcounting, which is +This lock will ideally be used for parentage, flags and naming, which is reasonable, since they are the only possible things to protect in the GstObject. + +Locking order +------------- + +In parent-child situations the lock of the parent must always be taken first +before taking the lock of the child. It is NOT allowed to hold the child +lock before taking the parent lock. + +This policy allows for parents to iterate their children and setting properties +on them. + +Whenever a nested lock needs to be taken on objects not involved in a +parent-child relation (eg. pads), an explictic locking order has to be defined. + + Path Generation --------------- -FIXME: rethink this ? Due to the base nature of the GstObject, it becomes the only reasonable place to put this particular function (_get_path_string). It will generate a string -describing the parent hierarchy of a given GstObject. Currently it is forced -to use several child-class-specific functions, because we do not properly use -the base capabilities (parentage, etc.) of GstObject properly. +describing the parent hierarchy of a given GstObject. + + +Flags +----- + +Each object in the GStreamer object hierarchy can have flags associated with it, +which are used to describe a state or a feature of the object. +GstObject has flags to mark its lifecycle: FLOATING, DISPOSING and DESTROYED. + + +Class signals +------------- + +It is possible to know when a new object is loaded by connecting to the +GstObjectClass signal. This feature is not very much used and might be removed +at some point. diff --git a/docs/design/part-relations.txt b/docs/design/part-relations.txt index f2deabbff4..a84e4477cf 100644 --- a/docs/design/part-relations.txt +++ b/docs/design/part-relations.txt @@ -1,6 +1,10 @@ Object relation types --------------------- +This document describes the relations between objects that exist in GStreamer. +It will also describe the way of handling the relation wrt locking and +refcounting. + 1) parent-child relation +---------+ +-------+ diff --git a/docs/design/part-standards.txt b/docs/design/part-standards.txt index c28b0246f8..bc29cea721 100644 --- a/docs/design/part-standards.txt +++ b/docs/design/part-standards.txt @@ -1,16 +1,40 @@ Ownership of dynamic objects ---------------------------- -Any object-oriented system or language that doesn't have automatic garbage collection has many potential pitfalls as -far as the pointers go. Therefore, some standards must be adhered to as far as who owns what. +Any object-oriented system or language that doesn't have automatic garbage +collection has many potential pitfalls as far as the pointers go. Therefore, +some standards must be adhered to as far as who owns what. -Strings: -Arguments passed into a function are owned by the caller, and the function will make a copy of the string for its own -internal use. The string should be const gchar *. Strings returned from a function remain the property of the -function called, and the caller must make a copy if it is to use the string for an extended duration. +Strings +------- + +Arguments passed into a function are owned by the caller, and the function +will make a copy of the string for its own internal use. The string should +be const gchar *. Strings returned from a function are always a copy of the +original and should be freed after usage by the caller. + + ex: + + name = gst_element_get_name (element); /* copy of name is made */ + .. use name .. + g_free (name); /* free after usage */ + + +Objects +------- + +Objects passed into a function are owned by the caller, any additional +reference held to the object after leaving the function should increase the +refcount of that object. + +Objects returned from a function are owned by the caller. This means that the +called should _free() or _unref() the object after usage. + + ex: + + peer = gst_pad_get_peer (pad); /* peer with increased refcount */ + if (peer) { + .. use peer .. + gst_object_unref (GST_OBJECT (peer)); /* unref peer after usage */ + } -Objects: -The ownership of an object during a function call depends on the type of function. If the function is simply returning -something from the object, such as _get_name(), the caller retains ownership. If the object passed is to be -manipulated in some way, it is generally the case that the function will take over the ownership. This should be -expressed as a reference increment on that object, but isn't in the general case (yet). diff --git a/libs/gst/control/dparam.c b/libs/gst/control/dparam.c index 32654c3aba..32b67c958c 100644 --- a/libs/gst/control/dparam.c +++ b/libs/gst/control/dparam.c @@ -1,7 +1,7 @@ /* GStreamer * Copyright (C) 2001 Steve Baker * - * gstdparam.c: Dynamic Parameter functionality + * gstdparam.c: Dynamic Parameter * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -247,10 +247,10 @@ gst_dparam_set_property (GObject * object, guint prop_id, const GValue * value, /** * gst_dparam_do_update_default: - * @dparam: - * @timestamp: - * @value: - * @update_info: + * @dparam: the parameter to update + * @timestamp: when should the update take place + * @value: the new value + * @update_info: unused here * * Default implementation for changing a dynamic parameter. * Subclasses might overwrite the behaviour of this. @@ -321,6 +321,7 @@ void gst_dparam_attach (GstDParam * dparam, GstDParamManager * manager, GParamSpec * param_spec, gchar * unit_name) { + GValue value = { 0, }; g_return_if_fail (dparam != NULL); g_return_if_fail (GST_IS_DPARAM (dparam)); @@ -339,6 +340,29 @@ gst_dparam_attach (GstDParam * dparam, GstDParamManager * manager, GST_DPARAM_IS_LOG (dparam) = gst_unitconv_unit_is_logarithmic (unit_name); GST_DEBUG ("attaching %s to dparam %p", GST_DPARAM_NAME (dparam), dparam); + // get default value from param-spec and set in dparam + g_value_init (&value, param_spec->value_type); + g_param_value_set_default (param_spec, &value); + switch (G_PARAM_SPEC_VALUE_TYPE (param_spec)) { + case G_TYPE_FLOAT: + dparam->value_float = g_value_get_float (&value); + break; + + case G_TYPE_DOUBLE: + dparam->value_double = g_value_get_double (&value); + break; + + case G_TYPE_INT: + dparam->value_int = g_value_get_int (&value); + break; + + case G_TYPE_INT64: + dparam->value_int64 = g_value_get_int64 (&value); + break; + + default: + break; + } } /** diff --git a/libs/gst/control/dparam.h b/libs/gst/control/dparam.h index 0ece3bf8cf..dfbbfd809e 100644 --- a/libs/gst/control/dparam.h +++ b/libs/gst/control/dparam.h @@ -55,7 +55,6 @@ G_BEGIN_DECLS typedef struct _GstDParamClass GstDParamClass; - typedef enum { GST_DPARAM_UPDATE_FIRST, GST_DPARAM_UPDATE_NORMAL diff --git a/libs/gst/control/dparammanager.c b/libs/gst/control/dparammanager.c index 61ce607c88..60deb39168 100644 --- a/libs/gst/control/dparammanager.c +++ b/libs/gst/control/dparammanager.c @@ -205,7 +205,10 @@ gst_dpman_add_required_dparam_callback (GstDParamManager * dpman, dpwrap = gst_dpman_new_wrapper (dpman, param_spec, unit_name, GST_DPMAN_CALLBACK); - g_return_val_if_fail (dpwrap != NULL, FALSE); + if (!dpwrap) { + GST_INFO ("failed to obtain a new dparam wrapper"); + return FALSE; + } GST_DEBUG ("adding required callback dparam '%s'", g_param_spec_get_name (param_spec)); @@ -244,7 +247,10 @@ gst_dpman_add_required_dparam_direct (GstDParamManager * dpman, dpwrap = gst_dpman_new_wrapper (dpman, param_spec, unit_name, GST_DPMAN_DIRECT); - g_return_val_if_fail (dpwrap != NULL, FALSE); + if (!dpwrap) { + GST_INFO ("failed to obtain a new dparam wrapper"); + return FALSE; + } GST_DEBUG ("adding required direct dparam '%s'", g_param_spec_get_name (param_spec)); @@ -282,7 +288,10 @@ gst_dpman_add_required_dparam_array (GstDParamManager * dpman, dpwrap = gst_dpman_new_wrapper (dpman, param_spec, unit_name, GST_DPMAN_ARRAY); - g_return_val_if_fail (dpwrap != NULL, FALSE); + if (!dpwrap) { + GST_INFO ("failed to obtain a new dparam wrapper"); + return FALSE; + } GST_DEBUG ("adding required array dparam '%s'", g_param_spec_get_name (param_spec)); @@ -353,7 +362,12 @@ gst_dpman_attach_dparam (GstDParamManager * dpman, const gchar * dparam_name, dpwrap = gst_dpman_get_wrapper (dpman, dparam_name); - g_return_val_if_fail (dpwrap != NULL, FALSE); + if (!dpwrap) { + GST_INFO ("failed to obtain get the dparam wrapper for parameter '%s'", + dparam_name); + return FALSE; + } + // FIXME: if these are triggered convert them to messages + returns as well g_return_val_if_fail (dpwrap->value != NULL, FALSE); g_return_val_if_fail (G_PARAM_SPEC_VALUE_TYPE (dpwrap->param_spec) == GST_DPARAM_TYPE (dparam), FALSE); @@ -407,7 +421,12 @@ gst_dpman_get_dparam (GstDParamManager * dpman, const gchar * dparam_name) g_return_val_if_fail (dparam_name != NULL, NULL); dpwrap = gst_dpman_get_wrapper (dpman, dparam_name); - g_return_val_if_fail (dpwrap != NULL, NULL); + + if (!dpwrap) { + GST_INFO ("failed to obtain get the dparam wrapper for parameter '%s'", + dparam_name); + return NULL; + } return dpwrap->dparam; } @@ -431,7 +450,12 @@ gst_dpman_get_dparam_type (GstDParamManager * dpman, const gchar * dparam_name) g_return_val_if_fail (dparam_name != NULL, 0); dpwrap = gst_dpman_get_wrapper (dpman, dparam_name); - g_return_val_if_fail (dpwrap != NULL, 0); + + if (!dpwrap) { + GST_INFO ("failed to obtain get the dparam wrapper for parameter '%s'", + dparam_name); + return 0; + } return G_VALUE_TYPE (dpwrap->value); } @@ -612,7 +636,7 @@ gst_dpman_set_parent (GstDParamManager * dpman, GstElement * parent) * Fetch the GstElement that parameters are handled by this manager. * * Returns: the GstDParamManager which belongs to this element or NULL - * if it doesn't exist + * if it doesn't exist. Do not call g_object_unref() on it. */ GstDParamManager * gst_dpman_get_manager (GstElement * parent) @@ -623,6 +647,7 @@ gst_dpman_get_manager (GstElement * parent) g_return_val_if_fail (GST_IS_ELEMENT (parent), NULL); dpman = (GstDParamManager *) g_hash_table_lookup (_element_registry, parent); + /* FIXME: shouldn't this be g_object_ref(dpman); */ return dpman; } @@ -649,7 +674,7 @@ gst_dpman_bypass_dparam (GstDParamManager * dpman, const gchar * dparam_name) g_return_if_fail (dpwrap != NULL); if (dpwrap->dparam != NULL) { - g_warning ("Bypassing attached dparam '%s'. It will be detached", + GST_WARNING ("Bypassing attached dparam '%s'. It will be detached", dparam_name); gst_dpman_detach_dparam (dpman, dparam_name); } @@ -835,7 +860,7 @@ gst_dpman_preprocess_asynchronous (GstDParamManager * dpman, guint frames, if (GST_DPMAN_RATE (dpman) == 0) { - g_warning ("The element hasn't given GstDParamManager a frame rate"); + GST_WARNING ("The element hasn't given GstDParamManager a frame rate"); return FALSE; } dpman->rate_ratio = (guint) (1000000000LL / (gint64) GST_DPMAN_RATE (dpman)); @@ -950,14 +975,14 @@ gst_dpman_process_asynchronous (GstDParamManager * dpman, guint frame_count) GST_DEBUG ("in gst_dpman_process_asynchronous"); if (frame_count >= dpman->num_frames) { - g_warning ("there is no more buffer to process"); + GST_WARNING ("there is no more buffer to process"); dpman->next_update_frame = dpman->num_frames; dpman->frames_to_process = 0; return FALSE; } if (frame_count != dpwrap->next_update_frame) { - g_warning ("frame count %u does not match update frame %u", + GST_WARNING ("frame count %u does not match update frame %u", frame_count, dpwrap->next_update_frame); } @@ -1040,7 +1065,7 @@ gst_dpman_preprocess_noop (GstDParamManager * dpman, guint frames, static gboolean gst_dpman_process_noop (GstDParamManager * dpman, guint frame_count) { - g_warning + GST_WARNING ("gst_dpman_process_noop should never be called - something might be wrong with your processing loop"); return FALSE; } diff --git a/libs/gst/control/dparammanager.h b/libs/gst/control/dparammanager.h index 7707e624f7..c5ee0be398 100644 --- a/libs/gst/control/dparammanager.h +++ b/libs/gst/control/dparammanager.h @@ -134,6 +134,9 @@ struct _GstDParamAsyncToUpdate { (dpman->next_update_frame < dpman->num_frames \ && (GST_DPMAN_PROCESSFUNC(dpman)(dpman, frame_count)))) +/* FIXME: this should pass dpwrap->dparam as the first arg + * the first arg in callback is usually object that triggered the callback + */ #define GST_DPMAN_CALLBACK_UPDATE(dpwrap, value) ((dpwrap->update_func)(value, dpwrap->update_data)) void _gst_dpman_initialize(void); diff --git a/tests/old/testsuite/clock/clock2.c b/tests/old/testsuite/clock/clock2.c index 116481e443..8271291962 100644 --- a/tests/old/testsuite/clock/clock2.c +++ b/tests/old/testsuite/clock/clock2.c @@ -8,8 +8,6 @@ #include -static GstClock *clock = NULL; - void gst_clock_debug (GstClock * clock, GstElement * fakesink) { @@ -34,6 +32,7 @@ element_wait (GstElement * element, GstClockTime time) int main (int argc, char *argv[]) { + GstClock *clock = NULL; GstElement *pipeline, *fakesrc, *fakesink; gst_init (&argc, &argv); diff --git a/tests/old/testsuite/threads/signals.c b/tests/old/testsuite/threads/signals.c index 8fc0cd3d85..e4fe4ce100 100644 --- a/tests/old/testsuite/threads/signals.c +++ b/tests/old/testsuite/threads/signals.c @@ -201,8 +201,10 @@ run_thread (GstTest * test) gst_test_do_signal2 (test); if (TESTNUM == 3) gst_test_do_prop (test); - if ((i++ % 10000) == 0) + if ((i++ % 10000) == 0) { g_print ("."); + g_usleep (1); /* context switch */ + } } return NULL; @@ -219,7 +221,7 @@ main (int argc, char **argv) test1 = g_object_new (GST_TYPE_TEST, NULL); test2 = g_object_new (GST_TYPE_TEST, NULL); - for (i = 0; i < 100; i++) { + for (i = 0; i < 20; i++) { g_thread_create ((GThreadFunc) run_thread, test1, TRUE, NULL); g_thread_create ((GThreadFunc) run_thread, test2, TRUE, NULL); } diff --git a/tests/old/testsuite/threads/thread.c b/tests/old/testsuite/threads/thread.c index 40eac8d687..4614c414a4 100644 --- a/tests/old/testsuite/threads/thread.c +++ b/tests/old/testsuite/threads/thread.c @@ -95,6 +95,7 @@ main (gint argc, gchar * argv[]) gst_element_set_state (pipeline, GST_STATE_PLAYING); g_print ("running ...\n"); while (gst_bin_iterate (GST_BIN (pipeline))); + g_print ("done ...\n"); gst_element_set_state (pipeline, GST_STATE_NULL); } if (TESTNUM == 4) { diff --git a/testsuite/clock/clock2.c b/testsuite/clock/clock2.c index 116481e443..8271291962 100644 --- a/testsuite/clock/clock2.c +++ b/testsuite/clock/clock2.c @@ -8,8 +8,6 @@ #include -static GstClock *clock = NULL; - void gst_clock_debug (GstClock * clock, GstElement * fakesink) { @@ -34,6 +32,7 @@ element_wait (GstElement * element, GstClockTime time) int main (int argc, char *argv[]) { + GstClock *clock = NULL; GstElement *pipeline, *fakesrc, *fakesink; gst_init (&argc, &argv); diff --git a/testsuite/threads/signals.c b/testsuite/threads/signals.c index 8fc0cd3d85..e4fe4ce100 100644 --- a/testsuite/threads/signals.c +++ b/testsuite/threads/signals.c @@ -201,8 +201,10 @@ run_thread (GstTest * test) gst_test_do_signal2 (test); if (TESTNUM == 3) gst_test_do_prop (test); - if ((i++ % 10000) == 0) + if ((i++ % 10000) == 0) { g_print ("."); + g_usleep (1); /* context switch */ + } } return NULL; @@ -219,7 +221,7 @@ main (int argc, char **argv) test1 = g_object_new (GST_TYPE_TEST, NULL); test2 = g_object_new (GST_TYPE_TEST, NULL); - for (i = 0; i < 100; i++) { + for (i = 0; i < 20; i++) { g_thread_create ((GThreadFunc) run_thread, test1, TRUE, NULL); g_thread_create ((GThreadFunc) run_thread, test2, TRUE, NULL); } diff --git a/testsuite/threads/thread.c b/testsuite/threads/thread.c index 40eac8d687..4614c414a4 100644 --- a/testsuite/threads/thread.c +++ b/testsuite/threads/thread.c @@ -95,6 +95,7 @@ main (gint argc, gchar * argv[]) gst_element_set_state (pipeline, GST_STATE_PLAYING); g_print ("running ...\n"); while (gst_bin_iterate (GST_BIN (pipeline))); + g_print ("done ...\n"); gst_element_set_state (pipeline, GST_STATE_NULL); } if (TESTNUM == 4) { diff --git a/tools/gst-launch.c b/tools/gst-launch.c index cc865bc8cd..d8314e48d6 100644 --- a/tools/gst-launch.c +++ b/tools/gst-launch.c @@ -143,15 +143,17 @@ fault_handler_sighandler (int signum) { fault_restore (); + /* printf is used instead of g_print(), since it's less likely to + * deadlock */ switch (signum) { case SIGSEGV: - g_print ("Caught SIGSEGV\n"); + printf ("Caught SIGSEGV\n"); break; case SIGQUIT: - g_print ("Caught SIGQUIT\n"); + printf ("Caught SIGQUIT\n"); break; default: - g_print ("signo: %d\n", signum); + printf ("signo: %d\n", signum); break; } @@ -165,17 +167,19 @@ fault_handler_sigaction (int signum, siginfo_t * si, void *misc) { fault_restore (); + /* printf is used instead of g_print(), since it's less likely to + * deadlock */ switch (si->si_signo) { case SIGSEGV: - g_print ("Caught SIGSEGV accessing address %p\n", si->si_addr); + printf ("Caught SIGSEGV accessing address %p\n", si->si_addr); break; case SIGQUIT: - g_print ("Caught SIGQUIT\n"); + printf ("Caught SIGQUIT\n"); break; default: - g_print ("signo: %d\n", si->si_signo); - g_print ("errno: %d\n", si->si_errno); - g_print ("code: %d\n", si->si_code); + printf ("signo: %d\n", si->si_signo); + printf ("errno: %d\n", si->si_errno); + printf ("code: %d\n", si->si_code); break; } @@ -194,7 +198,7 @@ fault_spin (void) wait (NULL); /* FIXME how do we know if we were run by libtool? */ - g_print ("Spinning. Please run 'gdb gst-launch %d' to continue debugging, " + printf ("Spinning. Please run 'gdb gst-launch %d' to continue debugging, " "Ctrl-C to quit, or Ctrl-\\ to dump core.\n", (gint) getpid ()); while (spinning) g_usleep (1000000);