int process_error(struct wiimote *wiimote, ssize_t len, struct mesg_array *ma) { struct cwiid_error_mesg *error_mesg; error_mesg = &ma->array[ma->count++].error_mesg; error_mesg->type = CWIID_MESG_ERROR; if (len == 0) { error_mesg->error = CWIID_ERROR_DISCONNECT; } else { error_mesg->error = CWIID_ERROR_COMM; } if (cancel_rw(wiimote)) { cwiid_err(wiimote, "RW cancel error"); } return 0; }
int cwiid_close(cwiid_wiimote_t *wiimote) { void *pthread_ret; int err; /* Stop rumbling, otherwise wiimote continues to rumble for few seconds after closing the connection! There should be no need to check if stopping fails: we are closing the connection in any case. */ if (wiimote->state.rumble) { cwiid_set_rumble(wiimote, 0); } /* Cancel and join router_thread and status_thread */ if (pthread_cancel(wiimote->router_thread)) { /* if thread quit abnormally, would have printed it's own error */ } err = pthread_join(wiimote->router_thread, &pthread_ret); if (err) { cwiid_err(wiimote, "Thread join error (router thread): %s", strerror(err)); } else if (!((pthread_ret == PTHREAD_CANCELED) || (pthread_ret == NULL))) { cwiid_err(wiimote, "Bad return value from router thread"); } if (pthread_cancel(wiimote->status_thread)) { /* if thread quit abnormally, would have printed it's own error */ } err = pthread_join(wiimote->status_thread, &pthread_ret); if (err) { cwiid_err(wiimote, "Thread join error (status thread): %s", strerror(err)); } else if (!((pthread_ret == PTHREAD_CANCELED) || (pthread_ret == NULL))) { cwiid_err(wiimote, "Bad return value from status thread"); } if (wiimote->mesg_callback) { if (cancel_mesg_callback(wiimote)) { /* prints it's own errors */ } } if (cancel_rw(wiimote)) { /* prints it's own errors */ } /* Close sockets */ if (close(wiimote->int_socket)) { cwiid_err(wiimote, "Socket close error (interrupt socket): %s", strerror(errno)); } if (close(wiimote->ctl_socket)) { cwiid_err(wiimote, "Socket close error (control socket): %s", strerror(errno)); } /* Close Pipes */ if (close(wiimote->mesg_pipe[0]) || close(wiimote->mesg_pipe[1])) { cwiid_err(wiimote, "Pipe close error (mesg pipe): %s", strerror(errno)); } if (close(wiimote->status_pipe[0]) || close(wiimote->status_pipe[1])) { cwiid_err(wiimote, "Pipe close error (status pipe): %s", strerror(errno)); } if (close(wiimote->rw_pipe[0]) || close(wiimote->rw_pipe[1])) { cwiid_err(wiimote, "Pipe close error (rw pipe): %s", strerror(errno)); } /* Destroy mutexes */ err = pthread_mutex_destroy(&wiimote->state_mutex); if (err) { cwiid_err(wiimote, "Mutex destroy error (state): %s", strerror(err)); } err = pthread_mutex_destroy(&wiimote->rw_mutex); if (err) { cwiid_err(wiimote, "Mutex destroy error (rw): %s", strerror(err)); } err = pthread_mutex_destroy(&wiimote->rpt_mutex); if (err) { cwiid_err(wiimote, "Mutex destroy error (rpt): %s", strerror(err)); } free(wiimote); return 0; }