@@ -56,6 +56,48 @@ struct pollfd_s
56
56
* Private Functions
57
57
****************************************************************************/
58
58
59
+ /****************************************************************************
60
+ * Name: poll_teardown
61
+ *
62
+ * Description:
63
+ * Teardown the poll operation for each descriptor in the list and return
64
+ * the count of non-zero poll events.
65
+ *
66
+ ****************************************************************************/
67
+
68
+ static inline void poll_teardown (FAR struct pollfd * fds , nfds_t nfds ,
69
+ FAR int * count )
70
+ {
71
+ unsigned int i ;
72
+
73
+ /* Process each descriptor in the list */
74
+
75
+ * count = 0 ;
76
+ for (i = 0 ; i < nfds ; i ++ )
77
+ {
78
+ if (fds [i ].fd >= 0 )
79
+ {
80
+ int status = poll_fdsetup (fds [i ].fd , & fds [i ], false);
81
+ if (status < 0 )
82
+ {
83
+ fds [i ].revents |= POLLERR ;
84
+ }
85
+ }
86
+
87
+ /* Check if any events were posted */
88
+
89
+ if (fds [i ].revents != 0 )
90
+ {
91
+ (* count )++ ;
92
+ }
93
+
94
+ /* Un-initialize the poll structure */
95
+
96
+ fds [i ].arg = NULL ;
97
+ fds [i ].cb = NULL ;
98
+ }
99
+ }
100
+
59
101
/****************************************************************************
60
102
* Name: poll_setup
61
103
*
@@ -68,8 +110,8 @@ static inline int poll_setup(FAR struct pollfd *fds, nfds_t nfds,
68
110
FAR sem_t * sem )
69
111
{
70
112
unsigned int i ;
71
- unsigned int j ;
72
113
int ret = OK ;
114
+ int count = 0 ;
73
115
74
116
/* Process each descriptor in the list */
75
117
@@ -101,76 +143,31 @@ static inline int poll_setup(FAR struct pollfd *fds, nfds_t nfds,
101
143
if (fds [i ].fd >= 0 )
102
144
{
103
145
ret = poll_fdsetup (fds [i ].fd , & fds [i ], true);
104
- }
105
-
106
- if (ret < 0 )
107
- {
108
- /* Setup failed for fds[i]. We now need to teardown previously
109
- * setup fds[0 .. (i - 1)] to release allocated resources and
110
- * to prevent memory corruption by access to freed/released 'fds'
111
- * and 'sem'.
112
- */
113
-
114
- for (j = 0 ; j < i ; j ++ )
146
+ if (ret < 0 )
115
147
{
116
- poll_fdsetup (fds [j ].fd , & fds [j ], false);
148
+ poll_teardown (fds , i , & count );
149
+ fds [i ].revents |= POLLERR ;
150
+ fds [i ].arg = NULL ;
151
+ fds [i ].cb = NULL ;
152
+ return count + 1 ;
153
+ }
154
+ else if (fds [i ].revents != 0 )
155
+ {
156
+ count ++ ;
117
157
}
118
-
119
- /* Indicate an error on the file descriptor */
120
-
121
- fds [i ].revents |= POLLERR ;
122
- return ret ;
123
158
}
124
159
}
125
160
126
- return OK ;
127
- }
128
-
129
- /****************************************************************************
130
- * Name: poll_teardown
131
- *
132
- * Description:
133
- * Teardown the poll operation for each descriptor in the list and return
134
- * the count of non-zero poll events.
135
- *
136
- ****************************************************************************/
137
-
138
- static inline int poll_teardown (FAR struct pollfd * fds , nfds_t nfds ,
139
- FAR int * count )
140
- {
141
- unsigned int i ;
142
- int status = OK ;
143
- int ret = OK ;
144
-
145
- /* Process each descriptor in the list */
146
-
147
- * count = 0 ;
148
- for (i = 0 ; i < nfds ; i ++ )
161
+ if (count > 0 )
149
162
{
150
- if (fds [i ].fd >= 0 )
151
- {
152
- status = poll_fdsetup (fds [i ].fd , & fds [i ], false);
153
- }
154
-
155
- if (status < 0 )
156
- {
157
- ret = status ;
158
- }
159
-
160
- /* Check if any events were posted */
161
-
162
- if (fds [i ].revents != 0 )
163
- {
164
- (* count )++ ;
165
- }
166
-
167
- /* Un-initialize the poll structure */
163
+ /* If there are already events available in poll_setup,
164
+ * we execute teardown and return immediately.
165
+ */
168
166
169
- fds [i ].arg = NULL ;
170
- fds [i ].cb = NULL ;
167
+ poll_teardown (fds , i , & count );
171
168
}
172
169
173
- return ret ;
170
+ return count ;
174
171
}
175
172
176
173
/****************************************************************************
@@ -425,8 +422,7 @@ int poll(FAR struct pollfd *fds, nfds_t nfds, int timeout)
425
422
FAR struct pollfd * kfds ;
426
423
sem_t sem ;
427
424
int count = 0 ;
428
- int ret2 ;
429
- int ret ;
425
+ int ret = OK ;
430
426
431
427
DEBUGASSERT (nfds == 0 || fds != NULL );
432
428
@@ -458,8 +454,13 @@ int poll(FAR struct pollfd *fds, nfds_t nfds, int timeout)
458
454
/* Set up the poll structure */
459
455
460
456
nxsem_init (& sem , 0 , 0 );
461
- ret = poll_setup (kfds , nfds , & sem );
462
- if (ret >= 0 )
457
+
458
+ /* If there are already events available in poll_setup,
459
+ * we return immediately
460
+ */
461
+
462
+ count = poll_setup (kfds , nfds , & sem );
463
+ if (count == 0 )
463
464
{
464
465
struct pollfd_s fdsinfo ;
465
466
@@ -471,13 +472,7 @@ int poll(FAR struct pollfd *fds, nfds_t nfds, int timeout)
471
472
fdsinfo .nfds = nfds ;
472
473
tls_cleanup_push (tls_get_info (), poll_cleanup , & fdsinfo );
473
474
474
- if (timeout == 0 )
475
- {
476
- /* Poll returns immediately whether we have a poll event or not. */
477
-
478
- ret = OK ;
479
- }
480
- else if (timeout > 0 )
475
+ if (timeout > 0 )
481
476
{
482
477
/* "Implementations may place limitations on the granularity of
483
478
* timeout intervals. If the requested timeout interval requires
@@ -509,7 +504,7 @@ int poll(FAR struct pollfd *fds, nfds_t nfds, int timeout)
509
504
/* EINTR is the only other error expected in normal operation */
510
505
}
511
506
}
512
- else
507
+ else if ( timeout < 0 )
513
508
{
514
509
/* Wait for the poll event or signal with no timeout */
515
510
@@ -522,11 +517,7 @@ int poll(FAR struct pollfd *fds, nfds_t nfds, int timeout)
522
517
* Preserve ret, if negative, since it holds the result of the wait.
523
518
*/
524
519
525
- ret2 = poll_teardown (kfds , nfds , & count );
526
- if (ret2 < 0 && ret >= 0 )
527
- {
528
- ret = ret2 ;
529
- }
520
+ poll_teardown (kfds , nfds , & count );
530
521
531
522
/* Pop the cancellation point */
532
523
0 commit comments