⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 locks.c

📁 使用在嵌入式linux平台或pc机上的wave文件录制和播放软件
💻 C
字号:
/* $Header: /home/cvs/wavplay/locks.c,v 1.2 1999/12/04 00:01:20 wwg Exp $ * Warren W. Gay VE3WWG		Sat May 11 15:01:58 1996 *  * MANAGE LOCKS ON THE AUDIO DEVICE: * * 	X LessTif WAV Play : *  * 	Copyright (C) 1997  Warren W. Gay VE3WWG *  * This  program is free software; you can redistribute it and/or modify it * under the  terms  of  the GNU General Public License as published by the * Free Software Foundation version 2 of the License. *  * This  program  is  distributed  in  the hope that it will be useful, but * WITHOUT   ANY   WARRANTY;   without   even  the   implied   warranty  of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General * Public License for more details (see enclosed file COPYING). *  * You  should have received a copy of the GNU General Public License along * with this  program; if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. *  * Send correspondance to: *  * 	Warren W. Gay VE3WWG *  * Email: *	ve3wwg@yahoo.com *	wgay@mackenziefinancial.com * * $Log: locks.c,v $ * Revision 1.2  1999/12/04 00:01:20  wwg * Implement wavplay-1.4 release changes * * Revision 1.1.1.1  1999/11/21 19:50:56  wwg * Import wavplay-1.3 into CVS * * Revision 1.1  1997/04/14 00:19:33  wwg * Initial revision * */static const char rcsid[] = "@(#)locks.c $Revision: 1.2 $";#include <stdio.h>#include <stdarg.h>#include <stdlib.h>#include <string.h>#include <signal.h>#include <errno.h>#include <unistd.h>#include <sys/types.h>#include <sys/ipc.h>#include <sys/sem.h>#include "wavplay.h"static int SemUndo = SEM_UNDO;static ErrFunc v_erf;				/* Error reporting function */static int bTimedOut = 0;			/* True if SIGALRM is raised *//* * SIGALRM catcher: */static voidcatch_sigalrm(int signo) {	bTimedOut = 1;				/* Mark as timed out */}/* * Error reporting function for this source module: */static voiderr(const char *format,...) {	va_list ap;	if ( v_erf == NULL )		return;				/* Only report error if we have function */	va_start(ap,format);	v_erf(format,ap);			/* Use caller's supplied function */	va_end(ap);}/* * OpenDSPLocks  opens the existing set of 2 semaphores, or creates * and  initializes  the new set  if  it  does  not yet exist. This * program   chooses   not   to   release  the  IPC  resource  upon * termination,  since the  semphore creation and initialization is * not  an atomic operation, and can be prone to failure.  However, * it  the  IPC resource is removed by some other means (like ipcrm * command),  this  function  call  will create a new set using the * supplied IPC Key 'LockIPCKey'. * * NOTES: * * Two semphores are created in this set. Semaphore # 0 is intended * to be used as a /dev/dsp 'input lock' (play lock), and semaphore * # 1 is the /dev/dsp 'output lock' (record lock).  I doubt if the * record lock  is very useful, but there might be situations where * it is needed. * * Class F Reporting: */intOpenDSPLocks(key_t LockIPCKey,int SemUndoFlag,ErrFunc erf) {	int ipc;	int s;	int e;	int safety = 3;	union semun u;	static ushort init_sems[2] = { 1, 1 };		v_erf = erf;					/* Set error reporting function */	/*	 * Set the SEM_UNDO status :	 */	SemUndo = SemUndoFlag ? SEM_UNDO : 0;	/*	 * If semaphore already exists, just use it :	 */	while ( (ipc = semget(LockIPCKey,2,0666)) < 0 && --safety >= 0 ) {			/*		 * Failed to find it, try creating it :		 */		if ( (ipc = semget(LockIPCKey,2,IPC_CREAT|IPC_EXCL|0666)) < 0 && errno != EEXIST ) {			err("Unable to create a semaphore set for key 0x%lX",				sys_errlist[errno],				LockIPCKey);			return -1;	/* No system IPC resources? */		}		/*		 * Set already exists- timing error? Try again.		 */		if ( ipc < 0 ) {			sleep(1);	/* Allow creator time to init sems */			continue;	/* Try again */		}		/*		 * We created the semaphore set - initialize so that		 * each semaphore has the value 1 :		 */		u.array = &init_sems[0];		if ( (s = semctl(ipc,0,SETALL,u)) < 0 && errno == EIDRM ) {			/*			 * Another process removed our ipc resource :			 */			continue;	/* Try again */		}		if ( s < 0 ) {			/*			 * We failed to initialize!			 */			e = errno;			/* Save error */			semctl(ipc,0,IPC_RMID,NULL);	/* Destroy bad sems */			err("%s: Unable to initialize semaphore set values",sys_errlist[errno=e]);			return -1;			/* Return err ind. */		}	}	return ipc;	/* Return existing, or newly initialized sems */}/* * Lock the /dev/dsp device : * * playrecx : *	0	play lock *	1	record lock */intLockDSP(int ipc,int playrecx,ErrFunc erf,unsigned timeout_secs) {	int s;	int e;	static struct sembuf sops[1] = { { 0, -1, SEM_UNDO } };	v_erf = erf;					/* Set error reporting function */	sops[0].sem_num = playrecx;	sops[0].sem_flg = SemUndo;	bTimedOut = 0;					/* Reset the timeout flag */	if ( timeout_secs > 0 ) {		signal(SIGALRM,catch_sigalrm);		/* Prepare to catch SIGALRM */		alarm(timeout_secs);			/* Start the timer */	}	while ( (s = semop(ipc,sops,1)) < 0 && errno == EINTR )		if ( bTimedOut ) {			err("Timed out: locking the %s semaphore",playrecx?"Record":"Play");			errno = EAGAIN;			/* Mark as timed out */			s = -1;			goto xit;		}	if ( s < 0 )		err("%s: Locking the %s semaphore",sys_errlist[errno],playrecx?"Record":"Play");	/*	 * Exit this procedure:	 */xit:	e = errno;					/* Preserve errno for this exit */	alarm(0);	signal(SIGALRM,SIG_DFL);	errno = e;					/* Restore errno */	return s;}/* * Lock the /dev/dsp device : * * playrecx : *	0	play lock *	1	record lock */intUnlockDSP(int ipc,int playrecx,ErrFunc erf) {	int s;	static struct sembuf sops[1] = { { 0, +1, SEM_UNDO } };	v_erf = erf;					/* Set error reporting function */	sops[0].sem_num = playrecx;	sops[0].sem_flg = SemUndo;	while ( (s = semop(ipc,sops,1)) < 0 && errno == EINTR ) ;	if ( s < 0 )		err("%s: Unlocking the %s semaphore",			sys_errlist[errno],			playrecx?"Record":"Play");	return s;}/* $Source: /home/cvs/wavplay/locks.c,v $ */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -