Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit f3eb3eb

Browse files
David Nugentmithro
David Nugent
authored andcommittedJan 16, 2015
Ensure input stream is closed on error - addresses issue #95
* Add a "virtual" close function to the gstworker class, call this when error is handled * Add a "virtual" close function to the gsocketinputstream class, which ensures that the socket is closed rather than relying on unref at finalize * Add video caps to inputsrc pipeline so that video format errors are detected and handled directly * Add a kludge to redirect warnings that are actually errors to the correct handler
1 parent 07f0fc9 commit f3eb3eb

File tree

4 files changed

+72
-21
lines changed

4 files changed

+72
-21
lines changed
 

‎tools/gio/gsocketinputstream.c

+18-6
Original file line numberDiff line numberDiff line change
@@ -85,22 +85,32 @@ g_socket_input_stream_set_property (GObject * object,
8585
}
8686
}
8787

88+
static gboolean
89+
g_socket_input_stream_close (GInputStream * s,
90+
GCancellable * cancellable, GError ** error)
91+
{
92+
GSocketInputStreamX *stream = G_SOCKET_INPUT_STREAM (s);
93+
gboolean ret = TRUE;
94+
95+
if (stream->priv->socket) {
96+
ret = g_socket_close (stream->priv->socket, error);
97+
g_object_unref (stream->priv->socket);
98+
stream->priv->socket = NULL;
99+
}
100+
return ret;
101+
}
102+
88103
static void
89104
g_socket_input_stream_finalize (GObject * object)
90105
{
91106
GSocketInputStreamX *stream = G_SOCKET_INPUT_STREAM (object);
92107

93108
if (stream->priv->socket) {
94109
GError *error = NULL;
95-
/*
96-
g_print ("%s:%d: %s, %d\n", __FILE__, __LINE__, __FUNCTION__,
97-
g_socket_get_fd (stream->priv->socket));
98-
*/
99-
g_socket_close (stream->priv->socket, &error);
110+
g_socket_input_stream_close (&stream->parent_instance, NULL, &error);
100111
if (error) {
101112
//ERROR ("%s", error->message);
102113
}
103-
g_object_unref (stream->priv->socket);
104114
}
105115

106116
if (G_OBJECT_CLASS (g_socket_input_stream_parent_class)->finalize)
@@ -117,6 +127,7 @@ g_socket_input_stream_read (GInputStream * stream,
117127
buffer, count, TRUE, cancellable, error);
118128
}
119129

130+
120131
static void
121132
g_socket_input_stream_class_init (GSocketInputStreamXClass * klass)
122133
{
@@ -130,6 +141,7 @@ g_socket_input_stream_class_init (GSocketInputStreamXClass * klass)
130141
gobject_class->set_property = g_socket_input_stream_set_property;
131142

132143
ginputstream_class->read_fn = g_socket_input_stream_read;
144+
ginputstream_class->close_fn = g_socket_input_stream_close;
133145

134146
g_object_class_install_property (gobject_class, PROP_SOCKET,
135147
g_param_spec_object ("socket",

‎tools/gstcase.c

+18-7
Original file line numberDiff line numberDiff line change
@@ -90,24 +90,20 @@ gst_case_init (GstCase * cas)
9090
}
9191

9292
/**
93-
* @param cas The GstCase instance.
93+
* @param cas the GstCase instance.
9494
* @memberof GstCase
9595
*
96-
* Disposing from it's parent object.
97-
*
98-
* @see GObject
96+
* Closes/releases resources used by the GstCase
9997
*/
10098
static void
101-
gst_case_dispose (GstCase * cas)
99+
gst_case_close (GstCase * cas)
102100
{
103101
if (cas->stream) {
104-
#if 0
105102
GError *error = NULL;
106103
g_input_stream_close (cas->stream, NULL, &error);
107104
if (error) {
108105
ERROR ("%s", error->message);
109106
}
110-
#endif
111107
g_object_unref (cas->stream);
112108
cas->stream = NULL;
113109
}
@@ -121,6 +117,20 @@ gst_case_dispose (GstCase * cas)
121117
g_object_unref (cas->branch);
122118
cas->branch = NULL;
123119
}
120+
}
121+
122+
/**
123+
* @param cas The GstR (Case instance.
124+
* @memberof GstCase
125+
*
126+
* Disposing from it's parent object.
127+
*
128+
* @see GObject
129+
*/
130+
static void
131+
gst_case_dispose (GstCase * cas)
132+
{
133+
gst_case_close (cas);
124134
//INFO ("dispose %p", cas);
125135
G_OBJECT_CLASS (parent_class)->dispose (G_OBJECT (cas));
126136
}
@@ -546,4 +556,5 @@ gst_case_class_init (GstCaseClass * klass)
546556
worker_class->prepare = (GstWorkerPrepareFunc) gst_case_prepare;
547557
worker_class->get_pipeline_string = (GstWorkerGetPipelineStringFunc)
548558
gst_case_get_pipeline_string;
559+
worker_class->close = (GstWorkerCloseFunc) gst_case_close;
549560
}

‎tools/gstworker.c

+22-8
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@
3232
#include "gstworker.h"
3333
#include "gstswitchserver.h"
3434

35+
#include <string.h>
36+
3537
#define GST_WORKER_LOCK_PIPELINE(srv) (g_mutex_lock (&(srv)->pipeline_lock))
3638
#define GST_WORKER_UNLOCK_PIPELINE(srv) (g_mutex_unlock (&(srv)->pipeline_lock))
3739

@@ -400,10 +402,9 @@ gst_worker_stop_force (GstWorker * worker, gboolean force)
400402

401403
g_timeout_add (5,
402404
(GSourceFunc) gst_worker_state_ready_to_null_proxy, worker);
403-
}
404-
else if (state == GST_STATE_PLAYING) {
405+
} else if (state == GST_STATE_PLAYING) {
405406
/* Send an EOS to cleanly shutdown */
406-
gst_element_send_event (worker->pipeline, gst_event_new_eos());
407+
gst_element_send_event (worker->pipeline, gst_event_new_eos ());
407408

408409
/* Go to sleep until the EOS handler calls stop_force (worker, TRUE); */
409410
g_cond_wait (&worker->shutdown_cond, &worker->pipeline_lock);
@@ -457,6 +458,7 @@ static void
457458
gst_worker_handle_eos (GstWorker * worker)
458459
{
459460
gst_worker_stop_force (worker, TRUE);
461+
GST_WORKER_CLASS (G_OBJECT_GET_CLASS (worker))->close (worker);
460462
}
461463

462464
static void
@@ -489,16 +491,20 @@ gst_worker_handle_error (GstWorker * worker, GError * error, const char *debug)
489491
}
490492
ERROR ("DEBUG INFO:\n%s\n", debug);
491493

492-
#if 0
493494
gst_worker_stop (worker);
494-
#endif
495+
GstWorkerClass *worker_class = GST_WORKER_CLASS (G_OBJECT_GET_CLASS (worker));
496+
worker_class->close (worker);
495497
}
496498

497499
static void
498500
gst_worker_handle_warning (GstWorker * worker, GError * error,
499501
const char *debug)
500502
{
501-
WARN ("%s: %s (%s)", worker->name, error->message, debug);
503+
// kludge: some gstreamer "warnings" are apparently non-recoverable errors
504+
if (strstr (error->message, "error:") != NULL)
505+
gst_worker_handle_error (worker, error, debug);
506+
else
507+
WARN ("%s: %s (%s)", worker->name, error->message, debug);
502508
}
503509

504510
static void
@@ -609,7 +615,7 @@ gst_worker_pipeline_state_changed (GstWorker * worker,
609615
}
610616

611617
static GstBusSyncReply
612-
gst_worker_message_sync (GstBus * bus, GstMessage * message, GstWorker *worker)
618+
gst_worker_message_sync (GstBus * bus, GstMessage * message, GstWorker * worker)
613619
{
614620
switch (GST_MESSAGE_TYPE (message)) {
615621
case GST_MESSAGE_EOS:
@@ -782,7 +788,8 @@ gst_worker_prepare_unsafe (GstWorker * worker)
782788
if (!worker->watch)
783789
goto error_add_watch;
784790

785-
gst_bus_set_sync_handler (worker->bus, (GstBusSyncHandler) (gst_worker_message_sync), worker, NULL);
791+
gst_bus_set_sync_handler (worker->bus,
792+
(GstBusSyncHandler) (gst_worker_message_sync), worker, NULL);
786793

787794
if (workerclass->prepare && !workerclass->prepare (worker))
788795
goto error_prepare;
@@ -889,6 +896,12 @@ gst_worker_reset (GstWorker * worker)
889896
return ok;
890897
}
891898

899+
static void
900+
gst_worker_close (GstWorker * worker)
901+
{
902+
903+
}
904+
892905
/**
893906
* @brief Initialize GstWorkerClass.
894907
* @param klass The instance of GstWorkerClass.
@@ -934,4 +947,5 @@ gst_worker_class_init (GstWorkerClass * klass)
934947
klass->create_pipeline = gst_worker_create_pipeline;
935948
klass->null = gst_worker_null;
936949
klass->reset = gst_worker_reset;
950+
klass->close = gst_worker_close;
937951
}

‎tools/gstworker.h

+14
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,13 @@ typedef GstWorkerNullReturn (*GstWorkerNullFunc) (GstWorker * worker);
9191
*/
9292
typedef void (*GstWorkerAliveFunc) (GstWorker * worker);
9393

94+
/**
95+
* @brief worker virtual close function
96+
* @param worker The GstWorker instance.
97+
*/
98+
99+
typedef void (*GstWorkerCloseFunc) (GstWorker * worker);
100+
94101
/**
95102
* @class GstWorker
96103
* @struct _GstWorker
@@ -207,6 +214,13 @@ struct _GstWorkerClass
207214
* @param worker The GstWorker instance.
208215
*/
209216
gboolean (*reset) (GstWorker * worker);
217+
218+
/*
219+
* @brief Close the worker, deallocating and closing resources
220+
* @param worker The GstWorker instance.
221+
*/
222+
223+
void (*close) (GstWorker * worker);
210224
};
211225

212226
/**

0 commit comments

Comments
 (0)
Please sign in to comment.