#include #include #include #include #include #define MAX_BURST 10 #define INITIAL_LEAKY_RATE 1 int bucketLevel=0; int bucketSize= MAX_BURST; int leakingRate= INITIAL_LEAKY_RATE; pthread_mutex_t bucketLock = PTHREAD_MUTEX_INITIALIZER; pthread_cond_t bucketChange = PTHREAD_COND_INITIALIZER; sigset_t mask; void * leak(void * arg) { struct itimerval timerval; struct timeval period; int signo; period.tv_sec=1; period.tv_usec=0; timerval.it_interval=timerval.it_value=period; setitimer(ITIMER_REAL, & timerval, NULL); while (1) { signo=SIGINT; /* anything different from SIGALRM */ while(signo!=SIGALRM) sigwait(&mask, &signo); /* to wait for SIGALRM in a thread */ pthread_mutex_lock(&bucketLock); if (bucketLevel>0) bucketLevel-=leakingRate; pthread_mutex_unlock(&bucketLock); pthread_cond_signal(&bucketChange); } } int main(int argc, char * argv[]) { pthread_t tid; char c; int err; /* this is to handle signals in a thread. */ sigemptyset(&mask); /* here we initialize mask to an empty set */ sigaddset(&mask,SIGALRM); /* include SIGALRM in the set */ pthread_sigmask(SIG_BLOCK, &mask, NULL); /* block SIGALRM, so it is not sent to this thread */ err = pthread_create(&tid, NULL, leak, NULL); if (err != 0){ printf("can't create thread \n"); exit(0); } c = getchar(); while (c!=EOF) { pthread_mutex_lock(&bucketLock); while ( bucketLevel >= bucketSize) /* while bucket is full */ pthread_cond_wait(&bucketChange, &bucketLock); bucketLevel+=1; pthread_mutex_unlock(&bucketLock); putchar(c); fflush(stdout); c = getchar(); } exit(0); }