Ejemplo n.º 1
0
int cwiid_set_mesg_callback(cwiid_wiimote_t *wiimote,
                            cwiid_mesg_callback_t *callback)
{
	if (wiimote->mesg_callback) {
		if (cancel_mesg_callback(wiimote)) {
			/* prints it's own errors */
			return -1;
		}
	}

	wiimote->mesg_callback = callback;

	if (wiimote->mesg_callback) {
		if (pthread_create(&wiimote->mesg_callback_thread, NULL,
		                  (void *(*)(void *))&mesg_callback_thread, wiimote)) {
			cwiid_err(wiimote, "Thread creation error (callback thread)");
			return -1;
		}
	}

	return 0;
}
Ejemplo n.º 2
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;
}