void Spread_reconnect(int ret){ if(ret != -8 && ret != -11 && ret != -2) wack_alarm(EXIT, "Spread_reconnnect: Unexpected Error (%d)", ret); wack_alarm(PRINT,"connecting to %s", Spread_name); Clean_up(); if(Mbox >= 0) { SP_disconnect(Mbox); E_detach_fd( Mbox, READ_FD ); Mbox = -1; } /* connecting to the relevant Spread daemon, asking for group info */ if(spread_lock) { handle_reconnect(0, NULL); return; } ret = SP_connect( Spread_name, User, 0, 1, &Mbox, Private_group ) ; if(ret == ACCEPT_SESSION) { ret = SP_join( Mbox, Spread_group ); if( ret < 0 ) { SP_error( ret ); SP_disconnect( Mbox ); Mbox = -1; wack_alarm(PRINT, "Spread join on reconnect failed [%d].", ret); handle_reconnect(0, NULL); return; } } else { wack_alarm(PRINT, "Spread connect failed [%d].", ret); handle_reconnect(0, NULL); return; } /* State initializations */ State = BOOT; Old_maturity = 0; Maturity = 0; E_queue( Turn_mature, 0, 0, Maturity_timeout ); My.num_allocated = 0; strcpy(My.private_group_name, Private_group); E_attach_fd( Mbox, READ_FD, Handle_network, 0, NULL, HIGH_PRIORITY ); E_set_active_threshold( HIGH_PRIORITY ); }
static void set_state_wack_service_state(control_state *sess) { sess->state = WRITE_FD; sess->data.retint = htonl(-1); if(sess->operation == WACK_SERVICE_FAILURE) { sess->data.retint = htonl(0); spread_lock = 1; E_detach_fd(Mbox, READ_FD); SP_disconnect(Mbox); Mbox=-1; Clean_up(); } else if(sess->operation == WACK_SERVICE_SUCCESS) { sess->data.retint = htonl(0); spread_lock = 0; } Spread_reconnect(-8); }
void handle_control_session(int fd, int code, void *data) { int ret; control_state *sess = (control_state *)data; switch(sess->state) { case READ_FD: switch(sess->operation) { case READ_COMMAND: ret = read(fd, &sess->operation, 1); if(ret == 0) goto close_clean; if(ret < 0) { if(errno == EAGAIN || errno == EWOULDBLOCK) return; goto error; } if(new_command(sess)) goto error; if(set_event_mask(fd, sess)) goto error; break; default: goto error; } break; case WRITE_FD: switch(sess->operation) { case GET_WACK_STATE: ret = write(fd, sess->data.writing.buffer+sess->data.writing.written, sess->data.writing.size-sess->data.writing.written); if(ret == 0) goto error; if(ret<0) { if(errno == EAGAIN || errno == EWOULDBLOCK) return; goto error; } sess->data.writing.written += ret; if(sess->data.writing.written == sess->data.writing.size) { free(sess->data.writing.buffer); sess->operation = READ_COMMAND; sess->state = READ_FD; if(set_event_mask(fd, sess)) goto error; } break; case WACK_SERVICE_FAILURE: case WACK_SERVICE_SUCCESS: ret = write(fd, &sess->data.retint, sizeof(int)); if(ret == 0) goto error; if(ret<0) { if(errno == EAGAIN || errno == EWOULDBLOCK) return; goto error; } if(ret != sizeof(int)) goto error; sess->operation = READ_COMMAND; sess->state = READ_FD; if(set_event_mask(fd, sess)) goto error; break; default: goto error; } break; default: goto error; } return; error: wack_alarm(PRINT, "control session error: [fd=%d] %s\n\tState=%d, Operation=%d", fd, strerror(errno), sess->state, sess->operation); close_clean: E_detach_fd(fd, READ_FD); E_detach_fd(fd, WRITE_FD); free(sess); close(fd); }
static void User_command() { char command[130]; char mess[MAX_MESSLEN]; char group[80]; char groups[10][MAX_GROUP_NAME]; int num_groups; unsigned int mess_len; int ret; int i; for( i=0; i < sizeof(command); i++ ) command[i] = 0; if( fgets( command, 130, stdin ) == NULL ) Bye(); switch( command[0] ) { case 'j': ret = sscanf( &command[2], "%s", group ); if( ret < 1 ) { printf(" invalid group \n"); break; } ret = SP_join( Mbox, group ); if( ret < 0 ) SP_error( ret ); break; case 'l': ret = sscanf( &command[2], "%s", group ); if( ret < 1 ) { printf(" invalid group \n"); break; } ret = SP_leave( Mbox, group ); if( ret < 0 ) SP_error( ret ); break; case 's': num_groups = sscanf(&command[2], "%s%s%s%s%s%s%s%s%s%s", groups[0], groups[1], groups[2], groups[3], groups[4], groups[5], groups[6], groups[7], groups[8], groups[9] ); if( num_groups < 1 ) { printf(" invalid group \n"); break; } printf("enter message: "); if (fgets(mess, 200, stdin) == NULL) Bye(); mess_len = strlen( mess ); #ifdef _REENTRANT #ifdef __bsdi__ /* bsdi bug - doing a close when another thread blocks on the socket causes a seg fault */ ret = send( Mbox, mess, 0, 0 ); if( ret < 0 ) { SP_error( CONNECTION_CLOSED ); Bye(); } #endif /* __bsdi__ */ #endif /* _REENTRANT */ ret= SP_multigroup_multicast( Mbox, SAFE_MESS, num_groups, (const char (*)[MAX_GROUP_NAME]) groups, 1, mess_len, mess ); if( ret < 0 ) { SP_error( ret ); Bye(); } Num_sent++; break; case 'b': ret=sscanf( &command[2], "%s", group ); if( ret != 1 ) strcpy( group, "dummy_group_name" ); printf("enter size of each message: "); if (fgets(mess, 200, stdin) == NULL) Bye(); ret=sscanf(mess, "%u", &mess_len ); if( ret !=1 ) mess_len = Previous_len; if( mess_len > MAX_MESSLEN ) mess_len = MAX_MESSLEN; Previous_len = mess_len; printf("sending 10 messages of %u bytes\n", mess_len ); for( i=0; i<10; i++ ) { Num_sent++; sprintf( mess, "mess num %d ", Num_sent ); #ifdef _REENTRANT #ifdef __bsdi__ /* bsdi bug - doing a close when another thread blocks on the socket causes a seg fault */ ret = send( Mbox, mess, 0,0 ); if( ret < 0 ) { SP_error( CONNECTION_CLOSED ); Bye(); } #endif /* __bsdi__ */ #endif /* _REENTRANT */ ret= SP_multicast( Mbox, FIFO_MESS, group, 2, mess_len, mess ); if( ret < 0 ) { SP_error( ret ); Bye(); } printf("sent message %d (total %d)\n", i+1, Num_sent ); } break; #ifndef _REENTRANT case 'r': Read_message(); break; case 'p': ret = SP_poll( Mbox ); printf("Polling sais: %d\n", ret ); break; case 'e': E_attach_fd( Mbox, READ_FD, Read_message, 0, NULL, HIGH_PRIORITY ); break; case 'd': E_detach_fd( Mbox, READ_FD ); break; #endif /* _REENTRANT */ case 'q': Bye(); break; default: printf("\nUnknown commnad\n"); Print_menu(); break; } printf("\nUser> "); fflush(stdout); }