Project

General

Profile

oss.cc

Dmitry Vagin, October 19, 2015 08:26

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