--- /dev/null
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2013 Olaf Wintermann. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef ATOMIC_H
+#define ATOMIC_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef __gnu_linux__
+
+#define ws_atomic_inc32(intptr) __sync_fetch_and_add(intptr, 1)
+#define ws_atomic_dec32(intptr) __sync_fetch_and_sub(intptr, 1) - 1
+#define ws_atomic_add32(intptr, val) __sync_fetch_and_add(intptr, val)
+#define ws_atomic_sub32(intptr, val) __sync_fetch_and_sub(intptr, val)
+
+#elif defined(OSX)
+#include <libkern/OSAtomic.h>
+
+#define ws_atomic_inc32(intptr) OSAtomicIncrement32((volatile int32_t *)intptr)
+#define ws_atomic_dec32(intptr) OSAtomicDecrement32((volatile int32_t *)intptr)
+
+#elif defined(BSD)
+#define ws_atomic_inc32(intptr) __sync_fetch_and_add(intptr, 1)
+#define ws_atomic_dec32(intptr) __sync_fetch_and_sub(intptr, 1) - 1
+#define ws_atomic_add32(intptr, val) __sync_fetch_and_add(intptr, val)
+#define ws_atomic_sub32(intptr, val) __sync_fetch_and_sub(intptr, va
+#else
+// use atomic.h
+#include <atomic.h>
+
+#define ws_atomic_inc32(intptr) atomic_inc_32_nv(intptr)
+#define ws_atomic_dec32(intptr) atomic_dec_32_nv(intptr)
+// TODO
+
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ATOMIC_H */
+
#include "settings.h"
#include "playlist.h"
+#include "atomic.h"
+
extern char **environ;
#define STR_BUFSIZE 512
printf("waitpid: %d\n", status);
+ printf("wait_for_process player: %p\n", player);
player->isactive = FALSE;
player->status = status;
SetPlayerWindow(0);
+ PlayerUnref(player);
return NULL;
}
player->process = player_pid;
player->isactive = TRUE;
+ player->ref++;
pthread_t tid;
if(pthread_create(&tid, NULL, wait_for_process, player)) {
perror("pthread_create");
+ player->ref--;
}
return 0;
Player *player = malloc(sizeof(Player));
memset(player, 0, sizeof(Player));
+ player->ref = 1;
// start mpv
if(start_player_process(player, win)) {
- PlayerDestroy(player);
+ PlayerUnref(player);
return NULL;
}
// wait until IPC socket is ready
if(wait_for_ipc(player)) {
- PlayerDestroy(player);
+ PlayerUnref(player);
return NULL;
}
//close(player->log);
if(connect_to_ipc(player)) {
- PlayerDestroy(player);
+ PlayerUnref(player);
return NULL;
}
// set player in main window
if(win->player) {
- PlayerDestroy(win->player);
+ PlayerUnref(win->player);
}
win->player = player;
}
}
-void PlayerDestroy(Player *p) {
+void PlayerUnref(Player *p) {
if(p->log >= 0) {
close(p->log);
+ p->log = -1;
}
if(p->ipc >= 0) {
close(p->ipc);
- }
-
- if(p->tmp) {
- free(p->tmp);
+ p->ipc = -1;
}
if(p->isactive) {
kill(p->process, SIGTERM);
}
+ if(ws_atomic_dec32(&p->ref) > 0) {
+ return;
+ }
- SetPlayerWindow(0);
+ if(p->tmp) {
+ free(p->tmp);
+ }
+
+ SetPlayerWindow(0);
free(p);
}