Пример #1
0
static void *alarm_fade(void *arg)
{
    fader *vols = (fader *)arg;
    guint i;
    gint v;
    gint inc, diff, adiff;

    /* lock */
    pthread_mutex_lock(&fader_lock);

    /* slide volume */
    /* the Kaspar Giger way of fading, check the current mixer volume and
     * increment from there so that if you have some other app lowering the
     * volume at the same time, the alarm plugin will not ignore it.  If you have
     * some other app increasing the volume, then it could get louder than you expect
     * though - because the loop does not recalculate the difference each time.
     */

    /* difference between the 2 volumes */
    diff = vols->end - vols->start;
    adiff = abs(diff);

    /* Are we going up or down? */
    if(diff < 0)
        inc = -1;
    else
        inc = 1;

    aud_drct_set_volume_main((gint)vols->start);
    //for(i=0;i<(vols->end - vols->start);i++)
    for(i=0;i<adiff;i++)
    {
        //threadsleep((gfloat)fading / (vols->end - vols->start));
        threadsleep((gfloat)fading / (gfloat)adiff);
        aud_drct_get_volume_main(&v);
        aud_drct_set_volume_main(v + inc);
    }
    /* Setting the volume to the end volume sort of defeats the point if having
     * the code in there to allow other apps to control volume too :)
     */
    //aud_drct_set_volume_main((gint)vols->end);

    /* and */
    pthread_mutex_unlock(&fader_lock);

    AUDDBG("volume = %f%%\n", (gdouble)vols->end);
    return 0;
}
Пример #2
0
static void *alarm_stop_thread(void *args)
{
    gint currvol;
    fader fade_vols;
    alarm_thread_t f;

    AUDDBG("alarm_stop_thread\n");


    /* sleep for however long we are meant to be sleeping for until
     * its time to shut up
     */
    threadsleep(((stop_h * 60) + stop_m) * 60);

    AUDDBG("alarm_stop triggered\n");

    if (alarm_dialog)
        gtk_widget_destroy(alarm_dialog);

    aud_drct_get_volume_main(&currvol),

    /* fade back to zero */
    fade_vols.start = currvol;
    fade_vols.end = 0;

    /* The fader thread locks the fader_mutex now */
    f = alarm_thread_create(alarm_fade, &fade_vols, 0);

    pthread_join(f.tid, NULL);
    aud_drct_stop();

    /* might as well set the volume to something higher than zero so we
     * dont confuse the poor people who just woke up and cant work out why
     * theres no music playing when they press the little play button :)
     */
    aud_drct_set_volume_main(currvol);

    AUDDBG("alarm_stop done\n");
    return(NULL);
}
Пример #3
0
int bufread(int s, void *buf, int numel) {
		int numcall = 0, numthis = 0, numread = 0;

		while (numread<numel) {

				numthis = recv(s, (char*)buf+numread, numel-numread, 0);
				if (numthis<0) {
						perror("bufread");
						DEBUG(LOG_ERR, "error: bufread");
						break;
				}
				else if (numthis == 0)
						break;

				DEBUG(LOG_DEBUG, "bufread: read %d bytes", numthis);
				numread += numthis;
				numcall++;
				threadsleep(0.001);
		}
		DEBUG(LOG_DEBUG, "bufread: reading the complete buffer required %d calls", numcall);
		return numread;
}
Пример #4
0
int bufwrite(int s, void *buf, int numel) {
		int numcall = 0, numthis = 0, numwrite = 0;

		DEBUG(LOG_DEBUG, "bufwrite: request for %d bytes", numel);

		while (numwrite<numel) {

				numthis = send(s, (char*)buf+numwrite, numel-numwrite, 0);
				if (numthis<0) {
						perror("bufwrite");
						DEBUG(LOG_ERR, "error: bufwrite");
						break;
				}
				else if(numthis == 0)
						break;

				DEBUG(LOG_DEBUG, "bufwrite: wrote %d bytes", numthis);
				numwrite += numthis;
				numcall++;
				threadsleep(0.001);
		}
		DEBUG(LOG_DEBUG, "bufwrite: writing the complete buffer required %d calls", numcall);
		return numwrite;
}
Пример #5
0
/***********************************************************************
 * this thread listens to incoming TCP connections
 * if a connection is made by a client, it starts the tcpsocket function
 ***********************************************************************/
void *tcpserver(void *arg) {
		int c, retry;
		int fd = 0;

		/* these variables are for the socket */
		struct sockaddr_in sa;
		unsigned int b;
		int optval;

		/* these variables are for the threading */
		int rc;
		pthread_t tid;

#ifdef WIN32
		unsigned long enable = 0;
		WSADATA wsa;
#endif

		threadlocal_t threadlocal;
		threadlocal.fd = &fd;

		/* this is for debugging */
		pthread_mutex_lock(&mutexthreadcount);
		threadcount++;
		pthread_mutex_unlock(&mutexthreadcount);

		pthread_cleanup_push(cleanup_tcpserver, &threadlocal);

		/* the status contains the thread id when running, or zero when not running */
		pthread_mutex_lock(&mutexstatus);
		if (tcpserverStatus==0) {
				tcpserverStatus = 1;
				/* signal that this thread has started */
				pthread_cond_signal(&condstatus);
				pthread_mutex_unlock(&mutexstatus);
		}
		else {
				pthread_mutex_unlock(&mutexstatus);
				goto cleanup;
		}

#ifdef WIN32
		if(WSAStartup(MAKEWORD(1, 1), &wsa))
		{
				DEBUG(LOG_ERR, "tcpserver: cannot start sockets");
				/* FIXME should this be handled more explicitely? */
		}
#endif

		/* setup socket */
		if ((fd = socket(PF_INET, SOCK_STREAM, 0)) < 0) {
				perror("tcpserver socket");
				DEBUG(LOG_ERR, "error: tcpserver socket");
				goto cleanup;
		}

		/* place the socket in non-blocking mode, required to do thread cancelation */
#ifdef WIN32
		enable = 0;
		ioctlsocket(fd, FIONBIO, &enable);
#else
		optval = fcntl(fd, F_GETFL, NULL);
		optval = optval | O_NONBLOCK;
		if (fcntl(fd, F_SETFL, optval)<0) {
				perror("tcpserver fcntl");
				DEBUG(LOG_ERR, "error: tcpserver fcntl");
				goto cleanup;
		}
#endif

		/* change the receive timeout */
		/*
		   timeout.tv_sec  = 1;
		   timeout.tv_usec = 1;
		   if (setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(optval)) < 0) {
		   perror("tcpserver setsockopt");
		   DEBUG(LOG_ERR, "error: tcpserver setsockopt");
		   goto cleanup;
		   }
		 */

		/* prevend "bind: Address already in use" */
		/*
		   optval = 1;
		   if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const char*)&optval, sizeof(optval)) < 0) {
		   perror("tcpserver setsockopt");
		   DEBUG(LOG_ERR, "error: tcpserver setsockopt");
		   goto cleanup;
		   }
		 */

		/* set larger buffer */
		optval = SO_RCVBUF_SIZE;
		if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, (const char*)&optval, sizeof(optval)) < 0) {
				perror("tcpserver setsockopt");
				DEBUG(LOG_ERR, "error: tcpserver setsockopt");
				goto cleanup;
		}

		/* set larger buffer */
		optval = SO_SNDBUF_SIZE;
		if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, (const char*)&optval, sizeof(optval)) < 0) {
				perror("tcpserver setsockopt");
				DEBUG(LOG_ERR, "error: tcpserver setsockopt");
				goto cleanup;
		}

		/* disable the Nagle buffering algorithm */
		/*
		   optval = 1;
		   if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &optval, sizeof(optval)) < 0) {
		   perror("tcpserver setsockopt");
		   DEBUG(LOG_ERR, "error: tcpserver setsockopt");
		   goto cleanup;
		   }
		 */

		bzero(&sa, sizeof sa);
		b = sizeof sa;

		pthread_mutex_lock(&mutexhost);
		if (host->port==0)
		  host->port = DEFAULT_PORT;
		sa.sin_family = AF_INET;
		sa.sin_port   = htons(host->port);

		if (INADDR_ANY)
				sa.sin_addr.s_addr = htonl(INADDR_ANY);

		retry = 1000;
		while (retry>0) {
				if (bind(fd, (struct sockaddr *)&sa, sizeof sa)<0) {
						/* increment the port number and try again */
						host->port++;
						sa.sin_port = htons(host->port);
						retry--;
				}
				else {
						/* this signals that it was successful */
						retry = -1;
				}
		}
		DEBUG(LOG_DEBUG, "tcpserver: started on port %d, id = %\n", host->port, host->id);
		pthread_mutex_unlock(&mutexhost);

		if (retry==0) {
				/* it failed on mutliple attempts, give up */
				perror("tcpserver bind");
				DEBUG(LOG_ERR, "error: tcpserver bind");
				goto cleanup;
		}

		if (listen(fd, BACKLOG)<0) {
				perror("tcpserver listen");
				DEBUG(LOG_ERR, "error: tcpserver listen");
				goto cleanup;
		}

		for (;;) {
				/*
				 * If no pending connections are present on the queue, and the socket
				 * is not marked as non-blocking, accept() blocks the caller until a
				 * connection is present.  If the socket is marked non-blocking and
				 * no pending connections are present on the queue, accept() returns
				 * an error as described below.
				 */

				c = accept(fd, (struct sockaddr *)&sa, &b);

				if (c<0) {
#ifdef WIN32
						if(errno==0) {
								pthread_testcancel();
								threadsleep(ACCEPTSLEEP);
						}
						else {
								perror("tcpserver accept");
								DEBUG(LOG_ERR, "error: tcpserver accept");
								goto cleanup;
						}
#else
						if (errno==EWOULDBLOCK) {
								pthread_testcancel();
								threadsleep(ACCEPTSLEEP);
						}
						else {
								perror("tcpserver accept");
								perror("tcpserver accept");
								goto cleanup;
						}
#endif
				}

				else {
						DEBUG(LOG_DEBUG, "tcpserver: opened connection to client on socket %d", c);

						/* place the socket back in blocking mode, this is needed for tcpsocket  */
#ifdef WIN32
						enable = 0;
						ioctlsocket(c, FIONBIO, &enable);
#else
						optval = fcntl(c, F_GETFL, NULL);
						optval = optval & (!O_NONBLOCK);
						if (fcntl(c, F_SETFL, optval)<0) {
								perror("tcpserver fcntl");
								perror("tcpserver fcntl");
								goto cleanup;
						}
#endif

						/* deal with the incoming connection on the TCP socket in a seperate thread */
						/* rc = pthread_create(&tid, &attr, tcpsocket, (void *)c); */
						rc = pthread_create(&tid, NULL, tcpsocket, (void *)c);

						if (rc) {
								/* the code should never arrive here */
								DEBUG(LOG_ERR, "tcpserver: return code from pthread_create() is %d", rc);
								goto cleanup;
						}

						DEBUG(LOG_DEBUG, "tcpserver: c = %d, threadcount = %d", c, threadcount);
						pthread_detach(tid);
				}
		}

cleanup:
		printf(""); /* otherwise the pthread_cleanup_pop won't compile */
		pthread_cleanup_pop(1);
		return NULL;
}