void channel_destroy(t_channel *channel) { if (channel && channel->name) free(channel->name); if (channel && channel->users) user_release(channel->users); if (channel) free(channel); }
/* * High-level handling of logout requests * FIXME: Do we need to send some kind of "goodbye" packet first? * * FIXME: The official library attempts to finish up things for a few * seconds before forcing a logout. * An example is when playlists are modified. They're modified * on the local side immediately but syncing the changes to the * server might take additional time. */ static int process_logout_request(sp_session *session, struct request *req) { /* FIXME: We should probably cancel all requests in flight aswell */ /* If a login is still in process, cancel it here */ if(session->login) { /* * We ought to cancel a pending login request here. * Instead we rely on process_login_request() to detect * that session->login became NULL * */ login_release(session->login); session->login = NULL; } /* Get rid of our identity */ if(session->user) { user_release(session->user); session->user = NULL; } memset(session->country, 0, sizeof(session->country)); if(session->sock != -1) { #ifdef _WIN32 closesocket(session->sock); #else close(session->sock); #endif session->sock = -1; } session->connectionstate = SP_CONNECTION_STATE_LOGGED_OUT; /* Unregister all channels */ channel_fail_and_unregister_all(session); return request_set_result(session, req, SP_ERROR_OK, NULL); }
/* * Not present in the official library * XXX - Might not be thread safe? * */ SP_LIBEXPORT(sp_error) sp_session_release (sp_session *session) { /* Unregister channels */ DSFYDEBUG("Unregistering any active channels\n"); channel_fail_and_unregister_all(session); /* Kill player thread */ player_free(session); /* Kill networking thread */ DSFYDEBUG("Terminating network thread\n"); #ifdef _WIN32 TerminateThread(session->thread_io, 0); session->thread_io = (HANDLE)0; CloseHandle(session->idle_wakeup); CloseHandle(session->request_mutex); #else pthread_cancel(session->thread_io); pthread_join(session->thread_io, NULL); session->thread_io = (pthread_t)0; pthread_mutex_destroy(&session->request_mutex); pthread_cond_destroy(&session->idle_wakeup); #endif if(session->packet) buf_free(session->packet); if(session->login) login_release(session->login); playlistcontainer_release(session); if(session->hashtable_albums) hashtable_free(session->hashtable_albums); if(session->hashtable_artists) hashtable_free(session->hashtable_artists); if(session->hashtable_images) hashtable_free(session->hashtable_images); if(session->hashtable_tracks) hashtable_free(session->hashtable_tracks); if(session->user) user_release(session->user); if(session->hashtable_users) hashtable_free(session->hashtable_users); free(session->callbacks); /* Helper function for sp_link_create_from_string() */ libopenspotify_link_release(); free(session); DSFYDEBUG("Session released\n"); return SP_ERROR_OK; }