@@ -257,6 +257,7 @@ void eDVBCWHandler::threadLoop()
257257 const Connection& conn = conns_snapshot[i];
258258
259259 // Softcam → proxy_fd (and intercept CWs)
260+ bool softcam_disconnected = false ;
260261 if (pfds[softcam_idx].revents & POLLIN)
261262 {
262263 ssize_t n = ::read (conn.softcam_fd , buf, sizeof (buf));
@@ -283,31 +284,40 @@ void eDVBCWHandler::threadLoop()
283284 written += w;
284285 }
285286 }
287+ else if (n == 0 )
288+ {
289+ // EOF - softcam closed the connection
290+ eDebug (" [eDVBCWHandler] Softcam EOF on fd %d" , conn.softcam_fd );
291+ softcam_disconnected = true ;
292+ }
293+ else if (errno != EINTR && errno != EAGAIN)
294+ {
295+ eDebug (" [eDVBCWHandler] Softcam read error on fd %d: %m" , conn.softcam_fd );
296+ softcam_disconnected = true ;
297+ }
286298 }
287299
288300 // Handle softcam disconnect
289- if (pfds[softcam_idx].revents & (POLLHUP | POLLERR))
301+ if (softcam_disconnected || ( pfds[softcam_idx].revents & (POLLHUP | POLLERR) ))
290302 {
291- if (!(pfds[softcam_idx].revents & POLLIN)) // Only if no data pending
303+ eDebug (" [eDVBCWHandler] Softcam disconnected on fd %d" , conn.softcam_fd );
304+ // Close proxy_fd so ePMTClient gets connectionLost
305+ std::lock_guard<std::mutex> lock (m_connections_mutex);
306+ for (auto it = m_connections.begin (); it != m_connections.end (); ++it)
292307 {
293- eDebug (" [eDVBCWHandler] Softcam disconnected on fd %d" , conn.softcam_fd );
294- // Close proxy_fd so ePMTClient gets connectionLost
295- std::lock_guard<std::mutex> lock (m_connections_mutex);
296- for (auto it = m_connections.begin (); it != m_connections.end (); ++it)
308+ if (it->softcam_fd == conn.softcam_fd )
297309 {
298- if (it->softcam_fd == conn.softcam_fd )
299- {
300- ::close (it->softcam_fd);
301- ::close (it->proxy_fd);
302- m_connections.erase (it);
303- break ;
304- }
310+ ::close (it->softcam_fd);
311+ ::close (it->proxy_fd);
312+ m_connections.erase (it);
313+ break ;
305314 }
306- continue ;
307315 }
316+ continue ;
308317 }
309318
310319 // proxy_fd → softcam (CAPMT writes from ePMTClient)
320+ bool proxy_disconnected = false ;
311321 if (pfds[proxy_idx].revents & POLLIN)
312322 {
313323 ssize_t n = ::read (conn.proxy_fd , buf, sizeof (buf));
@@ -330,24 +340,31 @@ void eDVBCWHandler::threadLoop()
330340 written += w;
331341 }
332342 }
343+ else if (n == 0 )
344+ {
345+ eDebug (" [eDVBCWHandler] ePMTClient EOF on proxy_fd %d" , conn.proxy_fd );
346+ proxy_disconnected = true ;
347+ }
348+ else if (errno != EINTR && errno != EAGAIN)
349+ {
350+ eDebug (" [eDVBCWHandler] ePMTClient read error on proxy_fd %d: %m" , conn.proxy_fd );
351+ proxy_disconnected = true ;
352+ }
333353 }
334354
335355 // Handle ePMTClient disconnect
336- if (pfds[proxy_idx].revents & (POLLHUP | POLLERR))
356+ if (proxy_disconnected || ( pfds[proxy_idx].revents & (POLLHUP | POLLERR) ))
337357 {
338- if (!(pfds[proxy_idx].revents & POLLIN))
358+ eDebug (" [eDVBCWHandler] ePMTClient disconnected on proxy_fd %d" , conn.proxy_fd );
359+ std::lock_guard<std::mutex> lock (m_connections_mutex);
360+ for (auto it = m_connections.begin (); it != m_connections.end (); ++it)
339361 {
340- eDebug (" [eDVBCWHandler] ePMTClient disconnected on proxy_fd %d" , conn.proxy_fd );
341- std::lock_guard<std::mutex> lock (m_connections_mutex);
342- for (auto it = m_connections.begin (); it != m_connections.end (); ++it)
362+ if (it->proxy_fd == conn.proxy_fd )
343363 {
344- if (it->proxy_fd == conn.proxy_fd )
345- {
346- ::close (it->softcam_fd);
347- ::close (it->proxy_fd);
348- m_connections.erase (it);
349- break ;
350- }
364+ ::close (it->softcam_fd);
365+ ::close (it->proxy_fd);
366+ m_connections.erase (it);
367+ break ;
351368 }
352369 }
353370 }
0 commit comments