| 1162 | } |
| 1163 | |
| 1164 | void invokeCallbacks(CFRunLoopTimerRef timer, void *info) |
| 1165 | { |
| 1166 | modAudioOut out = info; |
| 1167 | |
| 1168 | out->callbackTimer = NULL; |
| 1169 | |
| 1170 | xsBeginHost(out->the); |
| 1171 | xsmcVars(1); |
| 1172 | |
| 1173 | upUseCount(out); |
| 1174 | |
| 1175 | while (out->pendingCallbackCount) { |
| 1176 | xsIntegerValue id, stream; |
| 1177 | |
| 1178 | pthread_mutex_lock(&out->mutex); |
| 1179 | id = out->pendingCallbacks[0].id; |
| 1180 | stream = out->pendingCallbacks[0].stream; |
| 1181 | |
| 1182 | out->pendingCallbackCount -= 1; |
| 1183 | if (out->pendingCallbackCount) |
| 1184 | c_memmove(out->pendingCallbacks, out->pendingCallbacks + 1, out->pendingCallbackCount * sizeof(modAudioOutPendingCallbackRecord)); |
| 1185 | pthread_mutex_unlock(&out->mutex); |
| 1186 | |
| 1187 | xsmcSetInteger(xsVar(0), id); |
| 1188 | xsTry { |
| 1189 | xsmcGet(xsResult, out->obj, xsID_callbacks); |
| 1190 | if (xsUndefinedType != xsmcTypeOf(xsResult)) { |
| 1191 | xsmcGetIndex(xsResult, xsResult, stream); |
| 1192 | if (xsmcIsCallable(xsResult)) |
| 1193 | xsCallFunction1(xsResult, out->obj, xsVar(0)); |
| 1194 | } |
| 1195 | else |
| 1196 | xsCall1(out->obj, xsID_callback, xsVar(0)); |
| 1197 | } |
| 1198 | xsCatch { |
| 1199 | } |
| 1200 | } |
| 1201 | |
| 1202 | xsEndHost(out->the); |
| 1203 | |
| 1204 | downUseCount(out); |
| 1205 | } |
| 1206 | |
| 1207 | // note: queueCallback relies on caller to lock mutex |
| 1208 | void queueCallback(modAudioOut out, xsIntegerValue id, xsIntegerValue stream) |
no test coverage detected