From b4304f243c6006eec3ca4b4ce2b19cfca703861a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Reinhard=20Ni=C3=9Fl?= Date: Thu, 12 Apr 2007 22:14:06 +0200 Subject: Extend ticket system for nonblocking ticket acquiries. The current code has a race condition which can block arbitrary threads that call for example xine_get_current_frame() until the stream gets unpaused again. This can happen when the internal ticket acquiration collides with a ticket revokation for example when another thread is going to pause the stream. There are a few situations where a port ticket needs to be acquired for calling a port function but where it is absolutely undesireable to get blocked for an undetermined period of time. Therefore the ticket system should be extended by nonblocking functions which allow ticket acquiration even when a ticket revokation is in progress. And in the case where blocking is not avoidable, it should simply be indicated that no ticket was acquired. The caller can then choose to repeat the call at a later point in time. --- src/xine-engine/xine_internal.h | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'src/xine-engine/xine_internal.h') diff --git a/src/xine-engine/xine_internal.h b/src/xine-engine/xine_internal.h index 30899a4b3..da6f88a7f 100644 --- a/src/xine-engine/xine_internal.h +++ b/src/xine-engine/xine_internal.h @@ -159,6 +159,15 @@ struct xine_ticket_s { * revocation or by other threads acquiring tickets */ void (*revoke)(xine_ticket_t *self, int atomic); + /* behaves like acquire() but doesn't block the calling thread; when + * the thread would have been blocked, 0 is returned otherwise 1 + * this function acquires a ticket even if ticket revocation is active */ + int (*acquire_nonblocking)(xine_ticket_t *self, int irrevocable); + + /* behaves like release() but doesn't block the calling thread; should + * be used in combination with acquire_nonblocking() */ + void (*release_nonblocking)(xine_ticket_t *self, int irrevocable); + void (*dispose)(xine_ticket_t *self); pthread_mutex_t lock; -- cgit v1.2.3 From bd88a5c94af0af727680606a22ec9414fba68366 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Reinhard=20Ni=C3=9Fl?= Date: Thu, 12 Apr 2007 22:33:26 +0200 Subject: Provide a function to query buffer usage. This function shall be used to poll the number of remaining frames from a certain point in time on until the reported numbers are all 0. At that point in time, the content on screen is identical to a certain state of the stream, at which for example, a hardcopy may be taken. --- src/xine-engine/xine_internal.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/xine-engine/xine_internal.h') diff --git a/src/xine-engine/xine_internal.h b/src/xine-engine/xine_internal.h index da6f88a7f..c88bcc904 100644 --- a/src/xine-engine/xine_internal.h +++ b/src/xine-engine/xine_internal.h @@ -366,6 +366,8 @@ struct xine_stream_s { * private function prototypes: */ +int _x_query_buffer_usage(xine_stream_t *stream, int *num_video_buffers, int *num_audio_buffers, int *num_video_frames, int *num_audio_frames) XINE_PROTECTED; + void _x_handle_stream_end (xine_stream_t *stream, int non_user) XINE_PROTECTED; /* report message to UI. usually these are async errors */ -- cgit v1.2.3 From 0638ad373d88c3ed45273a505df56626daba19a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Reinhard=20Ni=C3=9Fl?= Date: Fri, 13 Apr 2007 00:17:30 +0200 Subject: Provide ability to lock port rewiring. The idea is to allow only a "single" frontend to rewire ports at a certain point in time. Regarding a stream, frontend_lock is used for example to allow only a single frontend to change the speed. Unfortunately, frontend_lock cannot be used as the rewire functions are not stream related. Therefore a new port_rewiring_lock was introduced and used at appropriate locations. When an arbitrary thread now holds the frontend_lock and the port_rewiring_lock, it is safe that acquiring a port ticket in functions like xine_get_current_frame() will never block the thread. --- src/xine-engine/xine_internal.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/xine-engine/xine_internal.h') diff --git a/src/xine-engine/xine_internal.h b/src/xine-engine/xine_internal.h index da6f88a7f..e11c3e667 100644 --- a/src/xine-engine/xine_internal.h +++ b/src/xine-engine/xine_internal.h @@ -168,6 +168,9 @@ struct xine_ticket_s { * be used in combination with acquire_nonblocking() */ void (*release_nonblocking)(xine_ticket_t *self, int irrevocable); + int (*lock_port_rewiring)(xine_ticket_t *self, int ms_timeout); + void (*unlock_port_rewiring)(xine_ticket_t *self); + void (*dispose)(xine_ticket_t *self); pthread_mutex_t lock; @@ -179,6 +182,7 @@ struct xine_ticket_s { int pending_revocations; int atomic_revoke; pthread_t atomic_revoker_thread; + pthread_mutex_t port_rewiring_lock; #endif }; -- cgit v1.2.3 From 31bb62fae17fe849704c5d3fe78090a3df92cead Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Reinhard=20Ni=C3=9Fl?= Date: Fri, 13 Apr 2007 00:32:19 +0200 Subject: Provide internal functions to lock port rewiring. The introduced function give "frontend like" plugins a chance to lock and unlock port rewiring. This protects such threads (when combined with holding the frontend lock) from beeing blocked when calling functions like xine_get_current_frame(). --- src/xine-engine/xine_internal.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/xine-engine/xine_internal.h') diff --git a/src/xine-engine/xine_internal.h b/src/xine-engine/xine_internal.h index db95d064a..4fa31a969 100644 --- a/src/xine-engine/xine_internal.h +++ b/src/xine-engine/xine_internal.h @@ -371,6 +371,8 @@ struct xine_stream_s { */ int _x_query_buffer_usage(xine_stream_t *stream, int *num_video_buffers, int *num_audio_buffers, int *num_video_frames, int *num_audio_frames) XINE_PROTECTED; +int _x_lock_port_rewiring(xine_t *xine, int ms_to_time_out) XINE_PROTECTED; +void _x_unlock_port_rewiring(xine_t *xine) XINE_PROTECTED; void _x_handle_stream_end (xine_stream_t *stream, int non_user) XINE_PROTECTED; -- cgit v1.2.3 From f8e051109fc70cbf7acbfd6582bc2f6d03e6d93b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Reinhard=20Ni=C3=9Fl?= Date: Fri, 13 Apr 2007 00:39:06 +0200 Subject: Provide internal functions to lock frontend_lock. The introduced functions give "frontend like" plugins a chance to lock and unlock frontend_lock. This protects such threads for example from beeing blocked when changing the streams speed. --- src/xine-engine/xine_internal.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/xine-engine/xine_internal.h') diff --git a/src/xine-engine/xine_internal.h b/src/xine-engine/xine_internal.h index 4fa31a969..511b13a0d 100644 --- a/src/xine-engine/xine_internal.h +++ b/src/xine-engine/xine_internal.h @@ -373,6 +373,8 @@ struct xine_stream_s { int _x_query_buffer_usage(xine_stream_t *stream, int *num_video_buffers, int *num_audio_buffers, int *num_video_frames, int *num_audio_frames) XINE_PROTECTED; int _x_lock_port_rewiring(xine_t *xine, int ms_to_time_out) XINE_PROTECTED; void _x_unlock_port_rewiring(xine_t *xine) XINE_PROTECTED; +int _x_lock_frontend(xine_stream_t *stream, int ms_to_time_out) XINE_PROTECTED; +void _x_unlock_frontend(xine_stream_t *stream) XINE_PROTECTED; void _x_handle_stream_end (xine_stream_t *stream, int non_user) XINE_PROTECTED; -- cgit v1.2.3 From ee7faf25388d4a2890bf3fa55288391cfe04851a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Reinhard=20Ni=C3=9Fl?= Date: Sun, 15 Apr 2007 20:43:42 +0200 Subject: Provide a function to query for outstanding OSD events. This function shall be used to poll the number of outstanding OSD events from a certain point in time on until the reported number is 0. At that point in time, the content on screen is identical to a certain state of the stream, at which for example, a hardcopy may be taken. --- src/xine-engine/xine_internal.h | 1 + 1 file changed, 1 insertion(+) (limited to 'src/xine-engine/xine_internal.h') diff --git a/src/xine-engine/xine_internal.h b/src/xine-engine/xine_internal.h index 511b13a0d..f4041452d 100644 --- a/src/xine-engine/xine_internal.h +++ b/src/xine-engine/xine_internal.h @@ -375,6 +375,7 @@ int _x_lock_port_rewiring(xine_t *xine, int ms_to_time_out) XINE_PROTECTED; void _x_unlock_port_rewiring(xine_t *xine) XINE_PROTECTED; int _x_lock_frontend(xine_stream_t *stream, int ms_to_time_out) XINE_PROTECTED; void _x_unlock_frontend(xine_stream_t *stream) XINE_PROTECTED; +int _x_query_unprocessed_osd_events(xine_stream_t *stream) XINE_PROTECTED; void _x_handle_stream_end (xine_stream_t *stream, int non_user) XINE_PROTECTED; -- cgit v1.2.3