/* * This is started by accept_cb as a thread on a new connection. * Calls pd_getline and sends the data it gets to pds_process_line * until pd_getline > 0 and !pdss->pdss_should_close */ int pds_session_serve(const pds_session_t *arg) { pds_session_t *pdss = (pds_session_t *)arg; char *line = NULL; int res; #ifdef _MACOSX signal (SIGPIPE, SIG_IGN); #endif DPRINT(PUL_INFO, "Started new pds_session_serve thread"); pdss->pdss_errdesc[0] = 0; /* first thing - Authenticate */ if(pdss->pdss_auth) { if(pdss->pdss_auth((pds_session_t *)pdss)){ pu_log(PUL_WARN, pdss->pdss_id, "Authentication failed or bad version - closing connection"); goto authfailed; } } while ((res = pd_getline(pdss->pdss_readbuf, sizeof (pdss->pdss_readbuf), &pdss->pdss_bufcur, &pdss->pdss_buflen, pdss->pdss_read, pdss->pdss_close, pdss->pdss_rfd, &line, pdss->pdss_errdesc, sizeof (pdss->pdss_errdesc))) > 0 && !pdss->pdss_should_close) { pds_process_line((pds_session_t *)pdss, line); free(line); line=NULL; } authfailed: free(line); line=NULL; //Shut down the report thread pdss->pdss_should_close = 1; pthread_mutex_lock(&pdss->pdss_lock); if (pdss->pdss_report_thread) { void *status; //pthread_cond_wait(&pdss->pdss_report_cv, &pdss->pdss_lock); pthread_mutex_unlock(&pdss->pdss_lock); pthread_join(pdss->pdss_report_thread, &status); pthread_mutex_lock(&pdss->pdss_lock); } /* remove keys set to expire at end of session */ pdss->pdss_pd_lock(pdss->pdss_pd_lock_arg); plist_walk(pdss->pdss_expire, expired_key_cb, pdss->pdss_pd); plist_clear(&pdss->pdss_expire); /* write_pending will free pending notifications - it will NOT send them because we freed pdss_write */ pdss->pdss_write = NULL; ptree_walk(pdss->pdss_pending, PTREE_POSTORDER, write_pending, ipmcmp, pdss); assert(!pdss->pdss_pending); //ptree_clear(&pdss->pdss_pending); //pdss->pdss_pending = NULL; //clear the listener list - need to lock the dictionary, //because an add/remove could be enumerating the list as we free it otherwise. ptree_walk(pdss->pdss_notify_args, PTREE_POSTORDER, free_na_cb, nacmp, pdss); //ptree_clear(&pdss->pdss_notify_args); assert(!pdss->pdss_notify_args); //Close the socket pdss->pdss_close(pdss->pdss_wfd, NULL, 0); if(pdss->pdss_wfd != pdss->pdss_rfd) pdss->pdss_close(pdss->pdss_rfd, NULL, 0); pdss->pdss_wfd = pdss->pdss_rfd = INVALID_SOCKET; pdss->pdss_close = NULL; pu_log(PUL_INFO, pdss->pdss_id, "done - session closed"); pdss->pdss_pd_unlock(pdss->pdss_pd_lock_arg); pthread_mutex_unlock(&pdss->pdss_lock); //make sure no cb threads are running while(pdss->cb_threads_count) SLEEP(10); /* now free the pdss!! */ pds_session_free(pdss); pu_log(PUL_INFO, 0, "Exiting pds_session_serve thread"); return 0; }
/* * This is started by accept_cb as a thread on a new connection. * Calls pd_getline and sends the data it gets to pds_process_line * until pd_getline > 0 and !pdss->pdss_should_close */ int pds_session_serve(const pds_session_t *arg) { pds_session_t *pdss = (pds_session_t *)arg; char *line; int res; #ifdef _MACOSX signal (SIGPIPE, SIG_IGN); #endif pdss->pdss_errdesc[0] = 0; while ((res = pd_getline(pdss->pdss_readbuf, sizeof (pdss->pdss_readbuf), &pdss->pdss_bufcur, &pdss->pdss_buflen, pdss->pdss_read, pdss->pdss_close, pdss->pdss_rfd, &line, pdss->pdss_errdesc, sizeof (pdss->pdss_errdesc))) > 0 && !pdss->pdss_should_close) { pds_process_line((pds_session_t *)pdss, line); free(line); line=NULL; } free(line); line=NULL; pdss->pdss_should_close = 1; /*printf("Printing out expiring keys:\n"); plist_walk(pdss->pdss_expire, print_key, NULL); printf("DONE\n");*/ /* remove keys set to expire at end of session */ pdss->pdss_pd_lock(pdss->pdss_pd_lock_arg); plist_walk(pdss->pdss_expire, expired_key_cb, pdss->pdss_pd); plist_clear(&pdss->pdss_expire); pdss->pdss_pd_unlock(pdss->pdss_pd_lock_arg); pthread_mutex_lock(&pdss->pdss_lock); if (pdss->pdss_report_thread) { void *status; //pthread_cond_wait(&pdss->pdss_report_cv, &pdss->pdss_lock); pthread_mutex_unlock(&pdss->pdss_lock); pthread_join(pdss->pdss_report_thread, &status); pthread_mutex_lock(&pdss->pdss_lock); } ptree_walk(pdss->pdss_notify_args, PTREE_INORDER, free_na_cb, NULL); ptree_clear(&pdss->pdss_notify_args); pthread_mutex_unlock(&pdss->pdss_lock); /* write_pending will free pending notifications */ pdss->pdss_write = NULL; ptree_walk(pdss->pdss_pending, PTREE_INORDER, write_pending, pdss); ptree_clear(&pdss->pdss_pending); assert(!pdss->pdss_pending); assert(!pdss->pdss_notify_args); pu_log(PUL_INFO, pdss->pdss_id, "done - session closed"); /* now free the pdss!! */ pds_session_free(pdss); return res; }