int main(int argc, char ** argv) { shm_network_init(); while(1) { /* Listen for requests and handle them */ switch(shm_cmd[0]) { case SHM_CMD_NEW_SERVER: { /* * get_packet_ptr is expected to return the start of the string * that must be passed in while communicating with this process. */ shm_t * new_server = shm_connect(SHM_DEV_SERVER, get_packet_ptr(shm_cmd), get_packet_ptr(shm_cmd)); if(SHM_IS_ERR(new_server)) { /* The server creation failed. Send error to whoever requested the server */ send_err(new_server); } else { /* The server is good */ send_confirmation(new_server, sizeof(shm_t)); } break; } case SHM_CMD_NEW_CLIENT: { shm_id_unique_t * clientname = (shm_id_unique_t *)get_packet_ptr(shm_cmd); shm_t * new_client = shm_connect(SHM_DEV_CLIENT, clientname->server_id, clientname->unique_id); if(SHM_IS_ERR(new_client)) { /* The client creation failed. Send error to whoever requested the client */ send_err(new_client); } else { /* The client is good */ send_confirmation(new_client, sizeof(shm_t)); } break; } case SHM_CMD_DESTROY_SERVER: shm_disconnect((shm_t*)get_packet_ptr(shm_cmd)); shm_ack(NULL, 0); break; case SHM_CMD_DESTROY_CLIENT: shm_disconnect((shm_t*)get_packet_ptr(shm_cmd)); shm_ack(NULL, 0); break; case SHM_CMD_SEND: /* Send packet directly from client/server to device (server or client): */ shm_send_to_device((shm_packet_t*)get_packet_ptr(shm_cmd)); break; case 0: /* No requests being done */ default: /* Clear out cmd flag */ shm_ack(NULL, 0); } thread_sleep(); } shm_network_stopall(); return 0; /* The shared memory manager should never return */ }
// ------------------------------------------------------------------------ // Main loop the program runs in while connected to the server. // Receives, authenticates, sends confirmation, and executes actions from // the server. // ------------------------------------------------------------------------ int Racr::daemon(){ char packet[PACKET_SIZE + 1]; if( _state != CONNECTED ){ return FAIL; } while( _ethernet_client.connected() ){ if( _ethernet_client.available() ){ // Packet read failed, flush stream and continue // (the continue will then check for connection status) if( !read_packet(packet) ){ Serial.println("Read Failed"); _ethernet_client.flush(); continue; } // If authentication fails, skip ahead to next packet. if( !auth_packet(packet) ){ Serial.println("Auth Failed"); continue; } // If we can't tell the server we got the command, // do not execute the command! if( !send_confirmation(packet) ){ Serial.println("Receipt confirmation failed"); continue; } // Execute the given action. int action = extract_action(packet); int arg = extract_arg(packet); (*_action_funcs[action])(arg); } } Serial.println("Connection died =("); _ethernet_client.stop(); _state = CONNECTION_SHUTDOWN; return SUCCESS; }
static int confirm_msg(struct server_msg *msg, int code, int code_min) { switch(code) { case LB_OK: code_min = 0; break; case LB_DBERR: /* code_min already contains apropriate error code */ break; case LB_PROTO: code_min = EDG_WLL_IL_PROTO; break; default: code_min = EDG_WLL_IL_SYS; break; } return(send_confirmation(msg->receipt_to, code_min)); }
//----------------------------------------------------------------------------- static void process_message(TcpClientState *state) { int off = 0; switch (state->msg_type) { case TCP_MSG_CID: state->client_id = state->read_buf[0]; printf("Got CID: %d\n", state->client_id); break; case TCP_MSG_CMDS: /* parse message as chain fo commands */ state->newturn_callback(); *state->ticks += *(uint32_t*)(state->read_buf+off); off += 4; while (off != state->msg_size) { int cmdsize = command_size((Netcmd*)(state->read_buf+off)); Netcmd *cmd = malloc(cmdsize); memcpy(cmd, state->read_buf+off, cmdsize); off += cmdsize; queue_push(state->in, cmd); } state->waiting = 0; break; case TCP_MSG_SNAPSHOT: state->snapshot_callback(state->read_buf, state->msg_size); printf("Received snapshot. Confirming...\n"); send_confirmation(state); state->ready = 1; break; default: printf("error: no message to process.\n"); } state->msg_type = TCP_MSG_NONE; }
static int handle_cmd(il_octet_string_t *event, long offset) { char *job_id_s; struct event_queue *eq; int num_replies, num_threads = 0; int timeout, result; long receipt; struct timespec endtime; struct timeval tv; /* parse command */ if(parse_cmd(event->data, &job_id_s, &receipt, &timeout) < 0) return(0); #if defined(INTERLOGD_FLUSH) glite_common_log(IL_LOG_CATEGORY, LOG_PRIORITY_DEBUG, "received FLUSH command"); /* catchup with all neccessary event files */ if(job_id_s) { struct event_store *es = event_store_find(job_id_s, NULL); if(es == NULL) { goto cmd_error; } result = event_store_recover(es); /* NOTE: if flush had been stored in file, there would have been no need to lock the event_store at all */ event_store_release(es); if(result < 0) { glite_common_log(IL_LOG_CATEGORY, LOG_PRIORITY_ERROR, " error trying to catch up with event file: %s", error_get_msg()); clear_error(); } } else /* this call does not fail :-) */ event_store_recover_all(); glite_common_log(IL_LOG_CATEGORY, LOG_PRIORITY_DEBUG, " alerting threads to report status"); /* prevent threads from reporting too early */ if(pthread_mutex_lock(&flush_lock) < 0) { /*** this error is considered too serious to allow the program run anymore! set_error(IL_SYS, errno, "pthread_mutex_lock: error locking flush lock"); goto cmd_error; */ abort(); } /* wake up all threads */ if(job_id_s) { /* find appropriate queue */ eq = queue_list_get(job_id_s); if(eq == NULL) goto cmd_error; if(!event_queue_empty(eq) && !queue_list_is_log(eq)) { num_threads++; event_queue_cond_lock(eq); eq->flushing = 1; event_queue_wakeup(eq); event_queue_cond_unlock(eq); } } else { /* iterate over event queues */ for(eq=queue_list_first(); eq != NULL; eq=queue_list_next()) { if(!event_queue_empty(eq) && !queue_list_is_log(eq)) { num_threads++; event_queue_cond_lock(eq); eq->flushing = 1; event_queue_wakeup(eq); event_queue_cond_unlock(eq); } } } if(!bs_only) { eq = queue_list_get(NULL); if(eq == NULL) goto cmd_error; if(!event_queue_empty(eq)) { num_threads++; event_queue_cond_lock(eq); eq->flushing = 1; event_queue_wakeup(eq); event_queue_cond_unlock(eq); } } /* wait for thread replies */ num_replies = 0; result = 1; gettimeofday(&tv, NULL); endtime.tv_sec = tv.tv_sec + timeout; endtime.tv_nsec = 1000 * tv.tv_usec; while(num_replies < num_threads) { int ret; if((ret=pthread_cond_timedwait(&flush_cond, &flush_lock, &endtime)) < 0) { char buf[256]; il_strerror_r(errno, buf, sizeof(buf)); glite_common_log(IL_LOG_CATEGORY, LOG_PRIORITY_ERROR, " error waiting for thread reply: %s", buf); result = (ret == ETIMEDOUT) ? 0 : -1; break; } /* collect results from reporting threads */ if(job_id_s) { /* find appropriate queue */ eq = queue_list_get(job_id_s); if(eq == NULL) goto cmd_error; if(!queue_list_is_log(eq)) { event_queue_cond_lock(eq); if(eq->flushing == 2) { eq->flushing = 0; num_replies++; result = ((result == 1) || (eq->flush_result < 0)) ? eq->flush_result : result; } event_queue_cond_unlock(eq); } } else { /* iterate over event queues */ for(eq=queue_list_first(); eq != NULL; eq=queue_list_next()) { if(!queue_list_is_log(eq)) { event_queue_cond_lock(eq); if(eq->flushing == 2) { eq->flushing = 0; num_replies++; glite_common_log(IL_LOG_CATEGORY, LOG_PRIORITY_DEBUG, " thread reply: %d", eq->flush_result); result = ((result == 1) || (eq->flush_result < 0)) ? eq->flush_result : result; } event_queue_cond_unlock(eq); } } } if(!bs_only) { eq = queue_list_get(NULL); if(eq == NULL) goto cmd_error; event_queue_cond_lock(eq); if(eq->flushing == 2) { eq->flushing = 0; num_replies++; result = ((result == 1) || (eq->flush_result < 0)) ? eq->flush_result : result; } event_queue_cond_unlock(eq); } } /* prevent deadlock in next flush */ if(pthread_mutex_unlock(&flush_lock) < 0) abort(); /* report back to local logger */ switch(result) { case 1: result = 0; break; case 0: result = EDG_WLL_IL_EVENTS_WAITING; break; default: result = EDG_WLL_IL_SYS; break; } if(job_id_s) free(job_id_s); result = send_confirmation(receipt, result); if(result <= 0) glite_common_log(IL_LOG_CATEGORY, LOG_PRIORITY_ERROR, "handle_cmd: error sending status: %s", error_get_msg()); return(1); cmd_error: if(job_id_s) free(job_id_s); return(-1); #else return(0); #endif /* INTERLOGD_FLUSH */ }