diff options
author | toma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2009-11-25 17:56:58 +0000 |
---|---|---|
committer | toma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2009-11-25 17:56:58 +0000 |
commit | e2de64d6f1beb9e492daf5b886e19933c1fa41dd (patch) | |
tree | 9047cf9e6b5c43878d5bf82660adae77ceee097a /mpg123_artsplugin/mpg123/xfermem.c | |
download | tdemultimedia-e2de64d6f1beb9e492daf5b886e19933c1fa41dd.tar.gz tdemultimedia-e2de64d6f1beb9e492daf5b886e19933c1fa41dd.zip |
Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features.
BUG:215923
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdemultimedia@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'mpg123_artsplugin/mpg123/xfermem.c')
-rw-r--r-- | mpg123_artsplugin/mpg123/xfermem.c | 275 |
1 files changed, 275 insertions, 0 deletions
diff --git a/mpg123_artsplugin/mpg123/xfermem.c b/mpg123_artsplugin/mpg123/xfermem.c new file mode 100644 index 00000000..8e43dab4 --- /dev/null +++ b/mpg123_artsplugin/mpg123/xfermem.c @@ -0,0 +1,275 @@ +/* + * xfermem.c + * + * Oliver Fromme <[email protected]> + * Sun Apr 6 02:26:26 MET DST 1997 + * + * See xfermem.h for documentation/description. + */ + +#ifndef NOXFERMEM + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <errno.h> +#include <sys/types.h> +#include <sys/time.h> +#include <sys/uio.h> +#include <sys/mman.h> +#include <sys/socket.h> +#include <fcntl.h> + +#ifdef AIX +#include <sys/select.h> +#endif + +#include "mpg123.h" + +#ifndef USE_MMAP +#include <sys/ipc.h> +#include <sys/shm.h> +#endif + +extern int errno; + +#if defined (USE_MMAP) && defined(MAP_ANONYMOUS) && !defined(MAP_ANON) +#define MAP_ANON MAP_ANONYMOUS +#endif + +void xfermem_init (txfermem **xf, int bufsize, int msize, int skipbuf) +{ + int regsize = bufsize + msize + skipbuf + sizeof(txfermem); + extern int preload; + +#ifdef USE_MMAP +# ifdef MAP_ANON + if ((*xf = (txfermem *) mmap(0, regsize, PROT_READ | PROT_WRITE, + MAP_ANON | MAP_SHARED, -1, 0)) == (txfermem *) -1) { + perror ("mmap()"); + exit (1); + } +# else + int devzero; + if ((devzero = open("/dev/zero", O_RDWR, 0)) == -1) { + perror ("open(/dev/zero)"); + exit (1); + } + if ((*xf = (txfermem *) mmap(0, regsize, PROT_READ | PROT_WRITE, + MAP_SHARED, devzero, 0)) == (txfermem *) -1) { + perror ("mmap()"); + exit (1); + } + close (devzero); +# endif +#else + struct shmid_ds shmemds; + int shmemid; + if ((shmemid = shmget(IPC_PRIVATE, regsize, IPC_CREAT | 0600)) == -1) { + perror ("shmget()"); + exit (1); + } + if ((*xf = (txfermem *) shmat(shmemid, 0, 0)) == (txfermem *) -1) { + perror ("shmat()"); + shmctl (shmemid, IPC_RMID, &shmemds); + exit (1); + } + if (shmctl(shmemid, IPC_RMID, &shmemds) == -1) { + perror ("shmctl()"); + xfermem_done (*xf); + exit (1); + } +#endif + if (socketpair(AF_UNIX, SOCK_STREAM, 0, (*xf)->fd) < 0) { + perror ("socketpair()"); + xfermem_done (*xf); + exit (1); + } + (*xf)->freeindex = (*xf)->readindex = 0; + (*xf)->wakeme[0] = (*xf)->wakeme[1] = FALSE; + (*xf)->data = ((byte *) *xf) + sizeof(txfermem) + msize; + (*xf)->metadata = ((byte *) *xf) + sizeof(txfermem); + (*xf)->size = bufsize; + (*xf)->metasize = msize + skipbuf; + preload = bufsize>>3; +} + +void xfermem_done (txfermem *xf) +{ + if(!xf) + return; +#ifdef USE_MMAP + munmap ((caddr_t) xf, xf->size + xf->metasize + sizeof(txfermem)); +#else + if (shmdt((void *) xf) == -1) { + perror ("shmdt()"); + exit (1); + } +#endif +} + +void xfermem_init_writer (txfermem *xf) +{ + if(xf) + close (xf->fd[XF_READER]); +} + +void xfermem_init_reader (txfermem *xf) +{ + if(xf) + close (xf->fd[XF_WRITER]); +} + +int xfermem_get_freespace (txfermem *xf) +{ + int freeindex, readindex; + + if(!xf) + return 0; + + if ((freeindex = xf->freeindex) < 0 + || (readindex = xf->readindex) < 0) + return (0); + if (readindex > freeindex) + return ((readindex - freeindex) - 1); + else + return ((xf->size - (freeindex - readindex)) - 1); +} + +int xfermem_get_usedspace (txfermem *xf) +{ + int freeindex, readindex; + + if(!xf) + return 0; + + if ((freeindex = xf->freeindex) < 0 + || (readindex = xf->readindex) < 0) + return (0); + if (freeindex >= readindex) + return (freeindex - readindex); + else + return (xf->size - (readindex - freeindex)); +} + +int xfermem_getcmd (int fd, int block) +{ + fd_set selfds; + byte cmd; + + for (;;) { + struct timeval selto = {0, 0}; + + FD_ZERO (&selfds); + FD_SET (fd, &selfds); + /* #ifdef HPUX */ /* seems to trigger performance problems? strange */ +#if 0 + switch (select(FD_SETSIZE, (int *) &selfds, NULL, NULL, block ? NULL : &selto)) { +#else + switch (select(FD_SETSIZE, &selfds, NULL, NULL, block ? NULL : &selto)) { +#endif + case 0: + if (!block) + return (0); + continue; + case -1: + if (errno == EINTR) + continue; + return (-2); + case 1: + if (FD_ISSET(fd, &selfds)) + switch (read(fd, &cmd, 1)) { + case 0: /* EOF */ + return (-1); + case -1: + if (errno == EINTR) + continue; + return (-3); + case 1: + return (cmd); + default: /* ?!? */ + return (-4); + } + else /* ?!? */ + return (-5); + default: /* ?!? */ + return (-6); + } + } +} + +int xfermem_putcmd (int fd, byte cmd) +{ + for (;;) { + switch (write(fd, &cmd, 1)) { + case 1: + return (1); + case -1: + if (errno != EINTR) + return (-1); + } + } +} + +int xfermem_block (int readwrite, txfermem *xf) +{ + int myfd = xf->fd[readwrite]; + int result; + + xf->wakeme[readwrite] = TRUE; + if (xf->wakeme[1 - readwrite]) + xfermem_putcmd (myfd, XF_CMD_WAKEUP); + result = xfermem_getcmd(myfd, TRUE); + xf->wakeme[readwrite] = FALSE; + return ((result <= 0) ? -1 : result); +} + +#elif defined(WIN32) +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> +#include <sys/types.h> +#include <fcntl.h> + +#include "mpg123.h" + +extern int errno; + +void xfermem_init (txfermem **xf, int bufsize, int msize, int skipbuf) +{ +} +void xfermem_done (txfermem *xf) +{ +} +void xfermem_init_writer (txfermem *xf) +{ +} +void xfermem_init_reader (txfermem *xf) +{ +} +int xfermem_get_freespace (txfermem *xf) +{ + return 0; +} +int xfermem_get_usedspace (txfermem *xf) +{ + return 0; +} +int xfermem_getcmd (int fd, int block) +{ + return 0; +} +int xfermem_putcmd (int fd, byte cmd) +{ + return 0; +} +int xfermem_block (int readwrite, txfermem *xf) +{ + return 0; +} +#endif + +/* eof */ + |