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; }
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); }
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; }
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; }
/*********************************************************************** * 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; }