Project

General

Profile

oss.cc

Dmitry Vagin, October 20, 2015 14:52

 
1
--- src/oss4/oss.cc.orig        2015-05-31 03:28:37.000000000 +0500
2
+++ src/oss4/oss.cc        2015-10-20 17:48:51.942794000 +0500
3
@@ -20,12 +20,10 @@
4
  * the use of this software.
5
  */
6
 
7
-#include "oss.h"
8
-
9
 #include <libaudcore/audstrings.h>
10
 #include <libaudcore/runtime.h>
11
 
12
-#include <poll.h>
13
+#include "oss.h"
14
 
15
 constexpr StereoVolume to_stereo_volume(int vol)
16
     { return {vol & 0x00ff, vol >> 8}; }
17
@@ -42,9 +40,6 @@
18
  "exclusive", "FALSE",
19
  nullptr};
20
 
21
-static int poll_pipe[2];
22
-static pollfd poll_handles[2];
23
-
24
 bool OSSPlugin::init()
25
 {
26
     AUDDBG("Init.\n");
27
@@ -147,59 +142,6 @@
28
     fd = -1;
29
 }
30
 
31
-static bool poll_setup(int fd)
32
-{
33
-    if (pipe(poll_pipe))
34
-    {
35
-        AUDERR("Failed to create pipe: %s.\n", strerror(errno));
36
-        return false;
37
-    }
38
-
39
-    if (fcntl(poll_pipe[0], F_SETFL, O_NONBLOCK))
40
-    {
41
-        AUDERR("Failed to set O_NONBLOCK on pipe: %s.\n", strerror(errno));
42
-        close(poll_pipe[0]);
43
-        close(poll_pipe[1]);
44
-        return false;
45
-    }
46
-
47
-    poll_handles[0].fd = poll_pipe[0];
48
-    poll_handles[0].events = POLLIN;
49
-    poll_handles[1].fd = fd;
50
-    poll_handles[1].events = POLLOUT;
51
-
52
-    return true;
53
-}
54
-
55
-static void poll_sleep()
56
-{
57
-    if (poll(poll_handles, 2, -1) < 0)
58
-    {
59
-        AUDERR("Failed to poll: %s.\n", strerror(errno));
60
-        return;
61
-    }
62
-
63
-    if (poll_handles[0].revents & POLLIN)
64
-    {
65
-        char c;
66
-        while (read(poll_pipe[0], &c, 1) == 1)
67
-            ;
68
-    }
69
-}
70
-
71
-static void poll_wake()
72
-{
73
-    const char c = 0;
74
-    if (write(poll_pipe[1], &c, 1) < 0)
75
-        AUDERR("Failed to write to pipe: %s.\n", strerror(errno));
76
-}
77
-
78
-static void poll_cleanup()
79
-{
80
-    close(poll_pipe[0]);
81
-    close(poll_pipe[1]);
82
-}
83
-
84
 bool OSSPlugin::open_audio(int aud_format, int rate, int channels)
85
 {
86
     AUDDBG("Opening audio.\n");
87
@@ -209,11 +151,11 @@
88
 
89
     CHECK_NOISY(m_fd = open_device);
90
 
91
-    if (!poll_setup(m_fd))
92
-        goto CLOSE;
93
-
94
     format = oss_convert_aud_format(aud_format);
95
 
96
+    m_poll.fd = m_fd;
97
+    m_poll.events = POLLOUT;
98
+
99
     if (!set_format(format, rate, channels))
100
         goto FAILED;
101
 
102
@@ -237,8 +179,6 @@
103
     return true;
104
 
105
 FAILED:
106
-    poll_cleanup();
107
-CLOSE:
108
     close_device(m_fd);
109
     return false;
110
 }
111
@@ -247,23 +187,24 @@
112
 {
113
     AUDDBG("Closing audio.\n");
114
 
115
-    poll_cleanup();
116
     close_device(m_fd);
117
 }
118
 
119
 int OSSPlugin::write_audio(const void *data, int length)
120
 {
121
-    if (m_paused)
122
-        return 0;
123
-
124
-    int written = write(m_fd, data, length);
125
+    int written = 0;
126
 
127
-    if (written < 0)
128
+    if (!m_paused)
129
     {
130
-        if (errno != EAGAIN)
131
-            DESCRIBE_ERROR;
132
+        written = write(m_fd, data, length);
133
+
134
+        if (written < 0)
135
+        {
136
+            if (errno != EAGAIN)
137
+                DESCRIBE_ERROR;
138
 
139
-        return 0;
140
+            written = 0;
141
+        }
142
     }
143
 
144
     return written;
145
@@ -271,7 +212,19 @@
146
 
147
 void OSSPlugin::period_wait()
148
 {
149
-    poll_sleep();
150
+    pthread_mutex_lock(&m_mutex);
151
+    if (m_paused)
152
+    {
153
+        pthread_cond_wait(&m_cond, &m_mutex);
154
+        pthread_mutex_unlock(&m_mutex);
155
+        return;
156
+    }
157
+    pthread_mutex_unlock(&m_mutex);
158
+
159
+    if (poll(&m_poll, 1, 500) < 0)
160
+    {
161
+        AUDERR("Failed to poll: %s.\n", strerror(errno));
162
+    }
163
 }
164
 
165
 void OSSPlugin::drain()
166
@@ -298,7 +251,7 @@
167
     CHECK(ioctl, m_fd, SNDCTL_DSP_RESET, nullptr);
168
 
169
 FAILED:
170
-    poll_wake();
171
+    pthread_cond_broadcast(&m_cond);
172
 }
173
 
174
 void OSSPlugin::pause(bool pause)
175
@@ -313,7 +266,11 @@
176
 
177
 FAILED:
178
 #endif
179
+
180
+    pthread_mutex_lock(&m_mutex);
181
     m_paused = pause;
182
+    pthread_cond_broadcast(&m_cond);
183
+    pthread_mutex_unlock(&m_mutex);
184
 }
185
 
186
 StereoVolume OSSPlugin::get_volume()
187
@@ -351,10 +308,8 @@
188
     if (aud_get_bool("oss4", "save_volume"))
189
         aud_set_int("oss4", "volume", vol);
190
 
191
-    if (m_fd == -1 || !m_ioctl_vol)
192
-        return;
193
-
194
-    CHECK(ioctl, m_fd, SNDCTL_DSP_SETPLAYVOL, &vol);
195
+    if (m_ioctl_vol && m_fd != -1)
196
+        CHECK(ioctl, m_fd, SNDCTL_DSP_SETPLAYVOL, &vol);
197
 
198
     return;
199