You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tdemultimedia/mpg123_artsplugin/mpg123/xfermem.c

276 lines
5.1 KiB

/*
* xfermem.c
*
* Oliver Fromme <oliver.fromme@heim3.tu-clausthal.de>
* 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 */