Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
V
vlc
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Redmine
Redmine
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
videolan
vlc
Commits
bf6dcb5d
Commit
bf6dcb5d
authored
Jun 30, 2015
by
Rémi Denis-Courmont
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
input: add vlc_poll_i11e() for interruptible poll()
This is a generic and inefficient but functional implementation.
parent
b9d91820
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
194 additions
and
0 deletions
+194
-0
include/vlc_interrupt.h
include/vlc_interrupt.h
+22
-0
src/libvlccore.sym
src/libvlccore.sym
+1
-0
src/misc/interrupt.c
src/misc/interrupt.c
+171
-0
No files found.
include/vlc_interrupt.h
View file @
bf6dcb5d
...
@@ -26,6 +26,9 @@
...
@@ -26,6 +26,9 @@
#ifndef VLC_INTERRUPT_H
#ifndef VLC_INTERRUPT_H
# define VLC_INTERRUPT_H 1
# define VLC_INTERRUPT_H 1
# include <vlc_threads.h>
# include <vlc_threads.h>
struct
pollfd
;
/**
/**
* @defgroup interrupt Interruptible sleep
* @defgroup interrupt Interruptible sleep
* @{
* @{
...
@@ -49,6 +52,25 @@
...
@@ -49,6 +52,25 @@
*/
*/
VLC_API
int
vlc_sem_wait_i11e
(
vlc_sem_t
*
);
VLC_API
int
vlc_sem_wait_i11e
(
vlc_sem_t
*
);
/**
* Waits for file descriptors I/O events, a timeout, a signal or a VLC I/O
* interruption. Except for VLC I/O interruptions, this function behaves
* just like the standard poll().
*
* @note This function is always a cancellation point (as poll()).
* @see poll() manual page
*
* @param fds table of events to wait for
* @param nfds number of entries in the table
* @param timeout time to wait in milliseconds or -1 for infinite
*
* @return A strictly positive result represent the number of pending events.
* 0 is returned if the time-out is reached without events.
* -1 is returned if a VLC I/O interrupt occurs (and errno is set to EINTR)
* or if an error occurs.
*/
VLC_API
int
vlc_poll_i11e
(
struct
pollfd
*
,
unsigned
,
int
);
/**
/**
* @}
* @}
* @defgroup interrupt_context Interrupt context signaling and manipulation
* @defgroup interrupt_context Interrupt context signaling and manipulation
...
...
src/libvlccore.sym
View file @
bf6dcb5d
...
@@ -539,6 +539,7 @@ vlc_ngettext
...
@@ -539,6 +539,7 @@ vlc_ngettext
vlc_iconv
vlc_iconv
vlc_iconv_close
vlc_iconv_close
vlc_iconv_open
vlc_iconv_open
vlc_poll_i11e
vlc_sem_wait_i11e
vlc_sem_wait_i11e
vlc_interrupt_create
vlc_interrupt_create
vlc_interrupt_destroy
vlc_interrupt_destroy
...
...
src/misc/interrupt.c
View file @
bf6dcb5d
...
@@ -29,7 +29,13 @@
...
@@ -29,7 +29,13 @@
#include <stdbool.h>
#include <stdbool.h>
#include <stdlib.h>
#include <stdlib.h>
#ifdef HAVE_POLL
#include <poll.h>
#endif
#include <vlc_common.h>
#include <vlc_common.h>
#include <vlc_fs.h>
/* vlc_pipe */
#include "interrupt.h"
#include "interrupt.h"
#include "libvlc.h"
#include "libvlc.h"
...
@@ -231,3 +237,168 @@ int vlc_sem_wait_i11e(vlc_sem_t *sem)
...
@@ -231,3 +237,168 @@ int vlc_sem_wait_i11e(vlc_sem_t *sem)
return
vlc_interrupt_finish
(
ctx
);
return
vlc_interrupt_finish
(
ctx
);
}
}
#ifndef _WIN32
static
void
vlc_poll_i11e_wake
(
void
*
opaque
)
{
uint64_t
value
=
1
;
int
*
fd
=
opaque
;
int
canc
;
canc
=
vlc_savecancel
();
write
(
fd
[
1
],
&
value
,
sizeof
(
value
));
vlc_restorecancel
(
canc
);
}
static
void
vlc_poll_i11e_cleanup
(
void
*
opaque
)
{
vlc_interrupt_t
*
ctx
=
opaque
;
int
*
fd
=
ctx
->
data
;
vlc_interrupt_finish
(
ctx
);
close
(
fd
[
1
]);
close
(
fd
[
0
]);
}
static
int
vlc_poll_i11e_inner
(
struct
pollfd
*
restrict
fds
,
unsigned
nfds
,
int
timeout
,
vlc_interrupt_t
*
ctx
,
struct
pollfd
*
restrict
ufd
)
{
int
fd
[
2
];
int
ret
=
-
1
;
int
canc
;
/* TODO: cache this */
/* TODO: use eventfd on Linux */
if
(
vlc_pipe
(
fd
))
{
vlc_testcancel
();
errno
=
ENOMEM
;
return
-
1
;
}
for
(
unsigned
i
=
0
;
i
<
nfds
;
i
++
)
{
ufd
[
i
].
fd
=
fds
[
i
].
fd
;
ufd
[
i
].
events
=
fds
[
i
].
events
;
}
ufd
[
nfds
].
fd
=
fd
[
0
];
ufd
[
nfds
].
events
=
POLLIN
;
if
(
vlc_interrupt_prepare
(
ctx
,
vlc_poll_i11e_wake
,
fd
))
{
vlc_testcancel
();
errno
=
EINTR
;
goto
out
;
}
vlc_cleanup_push
(
vlc_poll_i11e_cleanup
,
ctx
);
ret
=
poll
(
ufd
,
nfds
+
1
,
timeout
);
for
(
unsigned
i
=
0
;
i
<
nfds
;
i
++
)
fds
[
i
].
revents
=
ufd
[
i
].
revents
;
if
(
ret
>
0
&&
ufd
[
nfds
].
revents
)
{
uint64_t
dummy
;
read
(
fd
[
0
],
&
dummy
,
sizeof
(
dummy
));
ret
--
;
}
vlc_cleanup_pop
();
if
(
vlc_interrupt_finish
(
ctx
))
{
errno
=
EINTR
;
ret
=
-
1
;
}
out:
canc
=
vlc_savecancel
();
close
(
fd
[
1
]);
close
(
fd
[
0
]);
vlc_restorecancel
(
canc
);
return
ret
;
}
int
vlc_poll_i11e
(
struct
pollfd
*
fds
,
unsigned
nfds
,
int
timeout
)
{
vlc_interrupt_t
*
ctx
=
vlc_threadvar_get
(
vlc_interrupt_var
);
if
(
ctx
==
NULL
)
return
poll
(
fds
,
nfds
,
timeout
);
int
ret
;
struct
pollfd
*
ufd
=
malloc
((
nfds
+
1
)
*
sizeof
(
*
ufd
));
if
(
unlikely
(
ufd
==
NULL
))
return
-
1
;
/* ENOMEM */
vlc_cleanup_push
(
free
,
ufd
);
ret
=
vlc_poll_i11e_inner
(
fds
,
nfds
,
timeout
,
ctx
,
ufd
);
vlc_cleanup_pop
();
free
(
ufd
);
return
ret
;
}
#else
/* _WIN32 */
static
void
CALLBACK
vlc_poll_i11e_wake_self
(
ULONG_PTR
data
)
{
(
void
)
data
;
/* Nothing to do */
}
static
void
vlc_poll_i11e_wake
(
void
*
opaque
)
{
#if !VLC_WINSTORE_APP
HANDLE
th
=
opaque
;
QueueUserAPC
(
vlc_poll_i11e_wake_self
,
th
,
0
);
#else
(
void
)
opaque
;
#endif
}
static
void
vlc_poll_i11e_cleanup
(
void
*
opaque
)
{
vlc_interrupt_t
*
ctx
=
opaque
;
HANDLE
th
=
ctx
->
data
;
vlc_interrupt_finish
(
ctx
);
CloseHandle
(
th
);
}
int
vlc_poll_i11e
(
struct
pollfd
*
fds
,
unsigned
nfds
,
int
timeout
)
{
vlc_interrupt_t
*
ctx
=
vlc_threadvar_get
(
vlc_interrupt_var
);
if
(
ctx
==
NULL
)
return
vlc_poll
(
fds
,
nfds
,
timeout
);
int
ret
=
-
1
;
HANDLE
th
;
if
(
!
DuplicateHandle
(
GetCurrentProcess
(),
GetCurrentThread
(),
GetCurrentProcess
(),
&
th
,
0
,
FALSE
,
DUPLICATE_SAME_ACCESS
))
{
errno
=
ENOMEM
;
return
-
1
;
}
if
(
vlc_interrupt_prepare
(
ctx
,
vlc_poll_i11e_wake
,
th
))
{
errno
=
EINTR
;
goto
out
;
}
vlc_cleanup_push
(
vlc_poll_i11e_cleanup
,
th
);
ret
=
vlc_poll
(
fds
,
nfds
,
timeout
);
vlc_cleanup_pop
();
if
(
vlc_interrupt_finish
(
ctx
))
{
errno
=
EINTR
;
ret
=
-
1
;
}
out:
CloseHandle
(
th
);
return
ret
;
}
#endif
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment