@@ -1729,13 +1729,80 @@ nc_ps_poll_session_io(struct nc_session *session, int io_timeout, time_t now_mon
17291729 return ret ;
17301730}
17311731
1732+ /**
1733+ * @brief Poll a single pspoll session.
1734+ *
1735+ * @param[in] ps_session pspoll session to poll.
1736+ * @param[in] now_mono Current monotonic timestamp.
1737+ * @return NC_PSPOLL_RPC if some application data are available.
1738+ * @return NC_PSPOLL_TIMEOUT if a timeout elapsed.
1739+ * @return NC_PSPOLL_SSH_CHANNEL if a new SSH channel has been created.
1740+ * @return NC_PSPOLL_SSH_MSG if just an SSH message has been processed.
1741+ * @return NC_PSPOLL_SESSION_TERM | NC_PSPOLL_SESSION_ERROR if session has been terminated.
1742+ * @return NC_PSPOLL_ERROR on other fatal errors.
1743+ */
1744+ static int
1745+ nc_ps_poll_sess (struct nc_ps_session * ps_session , time_t now_mono )
1746+ {
1747+ int ret = NC_PSPOLL_ERROR ;
1748+ char msg [256 ];
1749+
1750+ switch (ps_session -> state ) {
1751+ case NC_PS_STATE_NONE :
1752+ if (ps_session -> session -> status == NC_STATUS_RUNNING ) {
1753+ /* session is fine, work with it */
1754+ ps_session -> state = NC_PS_STATE_BUSY ;
1755+
1756+ ret = nc_ps_poll_session_io (ps_session -> session , NC_SESSION_LOCK_TIMEOUT , now_mono , msg );
1757+ switch (ret ) {
1758+ case NC_PSPOLL_SESSION_TERM | NC_PSPOLL_SESSION_ERROR :
1759+ ERR (ps_session -> session , "%s." , msg );
1760+ ps_session -> state = NC_PS_STATE_INVALID ;
1761+ break ;
1762+ case NC_PSPOLL_ERROR :
1763+ ERR (ps_session -> session , "%s." , msg );
1764+ ps_session -> state = NC_PS_STATE_NONE ;
1765+ break ;
1766+ case NC_PSPOLL_TIMEOUT :
1767+ #ifdef NC_ENABLED_SSH_TLS
1768+ case NC_PSPOLL_SSH_CHANNEL :
1769+ case NC_PSPOLL_SSH_MSG :
1770+ #endif /* NC_ENABLED_SSH_TLS */
1771+ ps_session -> state = NC_PS_STATE_NONE ;
1772+ break ;
1773+ case NC_PSPOLL_RPC :
1774+ /* let's keep the state busy, we are not done with this session */
1775+ break ;
1776+ }
1777+ } else {
1778+ /* session is not fine, let the caller know */
1779+ ret = NC_PSPOLL_SESSION_TERM ;
1780+ if (ps_session -> session -> term_reason != NC_SESSION_TERM_CLOSED ) {
1781+ ret |= NC_PSPOLL_SESSION_ERROR ;
1782+ }
1783+ ps_session -> state = NC_PS_STATE_INVALID ;
1784+ }
1785+ break ;
1786+ case NC_PS_STATE_BUSY :
1787+ /* it definitely should not be busy because we have the lock */
1788+ ERRINT ;
1789+ ret = NC_PSPOLL_ERROR ;
1790+ break ;
1791+ case NC_PS_STATE_INVALID :
1792+ /* we got it locked, but it will be freed, let it be */
1793+ ret = NC_PSPOLL_TIMEOUT ;
1794+ break ;
1795+ }
1796+
1797+ return ret ;
1798+ }
1799+
17321800API int
17331801nc_ps_poll (struct nc_pollsession * ps , int timeout , struct nc_session * * session )
17341802{
17351803 int ret = NC_PSPOLL_ERROR , r ;
17361804 uint8_t q_id ;
17371805 uint16_t i , j ;
1738- char msg [256 ];
17391806 struct timespec ts_timeout , ts_cur ;
17401807 struct nc_session * cur_session ;
17411808 struct nc_ps_session * cur_ps_session ;
@@ -1777,52 +1844,7 @@ nc_ps_poll(struct nc_pollsession *ps, int timeout, struct nc_session **session)
17771844 ret = NC_PSPOLL_ERROR ;
17781845 } else if (r == 1 ) {
17791846 /* no one else is currently working with the session, so we can, otherwise skip it */
1780- switch (cur_ps_session -> state ) {
1781- case NC_PS_STATE_NONE :
1782- if (cur_session -> status == NC_STATUS_RUNNING ) {
1783- /* session is fine, work with it */
1784- cur_ps_session -> state = NC_PS_STATE_BUSY ;
1785-
1786- ret = nc_ps_poll_session_io (cur_session , NC_SESSION_LOCK_TIMEOUT , ts_cur .tv_sec , msg );
1787- switch (ret ) {
1788- case NC_PSPOLL_SESSION_TERM | NC_PSPOLL_SESSION_ERROR :
1789- ERR (cur_session , "%s." , msg );
1790- cur_ps_session -> state = NC_PS_STATE_INVALID ;
1791- break ;
1792- case NC_PSPOLL_ERROR :
1793- ERR (cur_session , "%s." , msg );
1794- cur_ps_session -> state = NC_PS_STATE_NONE ;
1795- break ;
1796- case NC_PSPOLL_TIMEOUT :
1797- #ifdef NC_ENABLED_SSH_TLS
1798- case NC_PSPOLL_SSH_CHANNEL :
1799- case NC_PSPOLL_SSH_MSG :
1800- #endif /* NC_ENABLED_SSH_TLS */
1801- cur_ps_session -> state = NC_PS_STATE_NONE ;
1802- break ;
1803- case NC_PSPOLL_RPC :
1804- /* let's keep the state busy, we are not done with this session */
1805- break ;
1806- }
1807- } else {
1808- /* session is not fine, let the caller know */
1809- ret = NC_PSPOLL_SESSION_TERM ;
1810- if (cur_session -> term_reason != NC_SESSION_TERM_CLOSED ) {
1811- ret |= NC_PSPOLL_SESSION_ERROR ;
1812- }
1813- cur_ps_session -> state = NC_PS_STATE_INVALID ;
1814- }
1815- break ;
1816- case NC_PS_STATE_BUSY :
1817- /* it definitely should not be busy because we have the lock */
1818- ERRINT ;
1819- ret = NC_PSPOLL_ERROR ;
1820- break ;
1821- case NC_PS_STATE_INVALID :
1822- /* we got it locked, but it will be freed, let it be */
1823- ret = NC_PSPOLL_TIMEOUT ;
1824- break ;
1825- }
1847+ ret = nc_ps_poll_sess (cur_ps_session , ts_timeout .tv_sec );
18261848
18271849 /* keep RPC lock in this one case */
18281850 if (ret != NC_PSPOLL_RPC ) {
0 commit comments