void* producer(void* arg) { Chan* writer; int* buf; int id; id = GETID(arg); printf("Producer %d starting"ENDL,id); writer = Chan_Open(GETCHAN(arg),CHAN_WRITE); buf = (int*)Chan_Token_Buffer_Alloc(writer); do { buf[0] = InterlockedIncrement(&item); usleep(1); usleep(1); printf("Producer: item %4d [ + ] %d"ENDL, buf[0], id); #pragma omp critical { mymax(&pmax,*buf); } Chan_Next(writer,(void**)&buf,sizeof(int)); } while(!stop); Chan_Token_Buffer_Free(buf); Chan_Close(writer); printf("Producer %d exiting"ENDL,id); return NULL; }
void* consumer(void* arg) { Chan* reader; int* buf,id; id = GETID(arg); printf("Consumer %d starting\n",id); reader = Chan_Open(GETCHAN(arg),CHAN_READ); buf = (int*)Chan_Token_Buffer_Alloc(reader); while(CHAN_SUCCESS(Chan_Next(reader,(void**)&buf,sizeof(int)))) { //i=InterlockedDecrement(&item); printf("Consumer: item %4d [ - ] %d"ENDL, buf[0], id); #pragma omp critical { mymax(&cmax,buf[0]); } } Chan_Token_Buffer_Free(buf); Chan_Close(reader); printf("Consumer %d exiting"ENDL,id); return NULL; }
int qcs__parse_qchat_msg( const char * pmsg, ssize_t pmsg_len, qcs_msg * msg ) { char ch; assert( pmsg && pmsg_len && msg ); qcs__cleanupmsg(msg); GETCHAR(ch); switch(ch) { case '0': msg->msg = QCS_MSG_REFRESH_REQUEST; GETSTR(msg->src); break; case '1': msg->msg = QCS_MSG_REFRESH_ACK; GETSTR(msg->dst); GETSTR(msg->src); GETMODE(msg->umode); if( pmsg_len ) { /* check for `ACTIVE' bit in qc16 messages */ GETACTIVE(msg->uactive); } else { /* uactive=TRUE per default */ msg->uactive = 1; } break; case '2': msg->msg = QCS_MSG_CHANNEL_BROADCAST; GETCHAN(msg->chan); GETSTR(msg->src); GETSTR(msg->text); break; case '4': msg->msg = QCS_MSG_CHANNEL_JOIN; GETSTR(msg->src); GETCHAN(msg->chan); GETMODE(msg->umode); /*dummy byte skipped*/ break; case '5': msg->msg = QCS_MSG_CHANNEL_LEAVE; GETSTR(msg->src); GETCHAN(msg->chan); /*dummy*/ break; case 'A': msg->msg = QCS_MSG_CHANNEL_ME; GETCHAN(msg->chan); GETSTR(msg->src); GETSTR(msg->text); break; case '7': msg->msg = QCS_MSG_MESSAGE_ACK; GETMODE(msg->umode); GETSTR(msg->dst); GETSTR(msg->src); GETCHAR(ch); /* dummy */ GETSTR(msg->text); break; case 'E': msg->msg = QCS_MSG_MESSAGE_MASS; GETSTR(msg->src); GETSTR(msg->dst); GETSTR(msg->text); break; case '6': msg->msg = QCS_MSG_MESSAGE_SEND; GETSTR(msg->src); GETSTR(msg->dst); GETSTR(msg->text); break; case '3': msg->msg = QCS_MSG_RENAME; GETSTR(msg->src); GETSTR(msg->text); /*dummy*/ break; case 'D': msg->msg = QCS_MSG_MODE_CHANGE; GETSTR(msg->src); GETMODE(msg->umode); /* dummy byte passed by */ break; case 'M': msg->msg = QCS_MSG_ACTIVE_CHANGE; GETSTR(msg->src); GETACTIVE(msg->uactive); break; case 'C': msg->msg = QCS_MSG_TOPIC_REPLY; GETSTR(msg->dst); GETSTR(msg->text); /* add "Main" as msg->chan */ msg->chan = malloc(5); if(!msg->chan) { qcs__cleanupmsg(msg); errno = ENOMEM; return 0; } memcpy(msg->chan, "Main", 5); break; case 'B': msg->msg = QCS_MSG_TOPIC_CHANGE; GETSTR(msg->text); /* fill in "Main": this is unsupported in qc, * thus we need to fill it in */ msg->chan = malloc(5); if(!msg->chan) { qcs__cleanupmsg(msg); errno = ENOMEM; return 0; } memcpy(msg->chan, "Main", 5); break; case 'G': msg->msg = QCS_MSG_INFO_REPLY; GETSTR(msg->dst); GETSTR(msg->src); GETSTR(msg->text); /* skip 3 strings - not used */ GETSTR(msg->chan);free(msg->chan); GETSTR(msg->chan);free(msg->chan); GETSTR(msg->chan);free(msg->chan); GETSTR(msg->chan); GETSTR(msg->supp); break; case 'F': msg->msg = QCS_MSG_INFO_REQUEST; GETSTR(msg->dst); GETSTR(msg->src); break; case 'K': msg->msg = QCS_MSG_CHANMEMBER_REPLY; GETSTR(msg->dst); GETSTR(msg->chan); GETSTR(msg->src); break; case 'L': msg->msg = QCS_MSG_CHANMEMBER_REQUEST; GETSTR(msg->src); break; case 'O': msg->msg = QCS_MSG_CHANLIST_REPLY; GETSTR(msg->dst); GETSTR(msg->chan); break; case 'N': msg->msg = QCS_MSG_CHANLIST_REQUEST; GETSTR(msg->src); break; case 'H': GETCHAR(ch); switch(ch) { case '1': msg->msg = QCS_MSG_BEEP_ACK; break; case '0': msg->msg = QCS_MSG_BEEP_SEND; break; default: errno = ENOMSG; return 0; } GETSTR(msg->dst); GETSTR(msg->src); /* dummy byte when 'H1' */ break; case 'J': GETCHAR(ch); switch(ch) { case '0':msg->msg = QCS_MSG_PRIVATE_OPEN; break; case '1':msg->msg = QCS_MSG_PRIVATE_CLOSE; break; case '2':msg->msg = QCS_MSG_PRIVATE_TEXT; break; case '3':msg->msg = QCS_MSG_PRIVATE_ME; break; default: errno = ENOMSG; return 0; } GETSTR(msg->src); GETSTR(msg->dst); if(ch=='2'||ch=='3') { GETSTR(msg->text); } break; default: errno = ENOMSG; return 0; } return 1; }
int qcs__parse_vypress_msg( const char * src, int src_len, qcs_msg * msg ) { int parsed_ok; char ch; qcs__cleanupmsg(msg); /* check for signature consistency and duplicates */ if( src_len < (QCS_SIGNATURE_LENGTH + 2) ) { /* not a vypress extension packet */ errno = ENOMSG; return 0; } if( qcs__known_dup_entry(src+1)) { /* duplicate encountered: ignore */ return 1; } else { /* not seen before: register */ qcs__insert_dup_entry(src+1); } /* skip signature: already parsed */ src += QCS_SIGNATURE_LENGTH + 1; src_len -= QCS_SIGNATURE_LENGTH + 1; /* parse message contents */ switch( *(src++) ) { case 'B': msg->msg = QCS_MSG_TOPIC_CHANGE; GETCHAN(msg->chan); GETSTR(msg->text); break; case 'C': msg->msg = QCS_MSG_TOPIC_REPLY; GETSTR(msg->dst); GETCHAN(msg->chan); GETSTR(msg->text); break; case 'G': msg->msg = QCS_MSG_INFO_REPLY; GETSTR(msg->dst); GETSTR(msg->src); GETSTR(msg->text); GETSTR(msg->chan);free(msg->chan); GETSTR(msg->chan);free(msg->chan); GETSTR(msg->chan); GETSTR(msg->supp); break; default: /* where it doesn't diff: parse with qc parser */ parsed_ok = qcs__parse_qchat_msg(src-1, src_len, msg); /* flush msg id cache if the user has left the net * (seems like, vypress chat v1.0 repeats the same * msg id, if restarted: unseeded rand() ??) */ if(parsed_ok && msg->msg==QCS_MSG_CHANNEL_LEAVE && !strcasecmp(msg->chan, "main")) { qcs__cleanup_dup(); } return parsed_ok; } return 1; }