[gst-devel] Multi-threaded queueing locking issues
Matt Howell
matth at ridgerun.com
Wed Mar 21 21:49:41 CET 2001
Erik Walthinsen wrote:
> On Tue, 20 Mar 2001, Matt Howell wrote:
>
> > i don't think the check in gstpad.c::change_state() is such a bad thing. it's
> > called in the context of the thread (the pipeline?) which was instructed to
> > go to the pause state by the app, right? it's in gstpad.c because it's pad-
> > centric... maybe i don't understand your concern here.
> There is no pad_change_state()... Only the element_change_state, which is
> called within the context of the thread, but only after the thread has
> woken up from within its iteration, which is the whole problem.
doh! you're right. i meant gst_queue_change_state(). (s/pad/queue/g)
aren't the various change_state() calls called in the context of the app?
(a different context than the pipeline / thread containers?)
> > it doesn't seem bad to use different ways to wake threads that are blocked
> > for different reasons. if a thread is blocked because of g_cond_wait(), it
> > should be waked with g_cond_signal(). it it's blocked because of a system
> > call (e.g., blocking read) use the system kill().
> Only if we can unblock them all without killing the thread. While every
> element must be written so it has all of its live state within its own
> object struct (so they can be shut down and restarted at the beginning
> with no problems), there's still the problem of things like filehandles
> which will be opened from thread context. I just wrote a test that shows
> that at least with nothing else going on, it seems that filehandles stick
> around even when the thread that created them goes away. I have no idea
> if the same is true for other kinds of files.
the only case in which a thread would have to be killed (pthread cancel) is if
it's blocked on a system call (e.g., non-blocking read). in the more common
case of thread synchronization (where a thread is blocked because it called
g_cond_wait()), you do not have to kill the thread.
it seems the complication arises only in the blocking system call cases
(blocking read, blocking write). if we wrote an i/o library for filters, we
could manage this problem. these calls would be blocking as far as the
filter is concerned, but, internally, do the i/o in a non-blocking fashion.
for example,
// add to gst_element some persistent storage for file descriptors and associated
// flags... basically, only need to know if element opened for blocking i/o
int gst_open(gst_element *e, const char *pathname, int flags, mode_t mode)
{
int fd = open(pathname, (flags & ~(O_NONBLOCK | O_NDELAY));
if (flags & (O_NONBLOCK | O_NDELAY) && fd != -1)
{
// record blocking i/o for this fd in e's persistent data
}
return fd;
}
size_t gst_read(gst_element *e, fd, void *buf, size_t count)
{
if ( GST_FD_FLAGS(e,fd) & (O_NONBLOCK | O_NDELAY) )
{
int actual = 0;
while (count>0 && GST_STATE_PENDING(e) != STATE_PAUSED)
{
if ((actual = read(fd, buf, count)) < 0) return actual;
if (actual)
count -= actual; buf += actual;
else
// some timeout ... maybe usleep(100) ??
}
}
else
return read(fd, buf, count);
}
however, such an approach may break certain uses of a "blocking" call.
any thoughts? problems?
matt.
> > the spin / timeout stuff could be encapsulated in an element's change_state().
> > (this requires that all elements that can block on a system call implement
> > their own change_state().) as brent points out below, this could use
> > pthread_cancel() (assuming these elements are in a pthread) as a last resort
> > (since it is a bit destructive ;-).
> Remember though that change_state doesn't happen for an element until the
> thread has been unblocked anyway, because the change_state happens from
> thread context. The thread has to be told to do the change_state... And
> pthread_cancel() has the potential problem of blowing away per-thread
> state.
>
> Erik Walthinsen <omega at temple-baptist.com> - System Administrator
> __
> / \ GStreamer - The only way to stream!
> | | M E G A ***** http://gstreamer.net/ *****
> _\ /_
>
> _______________________________________________
> gstreamer-devel mailing list
> gstreamer-devel at lists.sourceforge.net
> http://lists.sourceforge.net/lists/listinfo/gstreamer-devel
More information about the gstreamer-devel
mailing list