@@ -37,9 +37,10 @@ bool incr_combined_sequence(struct sonyflake_state *self) {
3737 return self -> combined_sequence == 0 ;
3838}
3939
40- static inline void get_relative_current_time (struct sonyflake_state * self , struct timespec * now ) {
40+ static inline void get_relative_current_time (struct sonyflake_state * self , struct timespec * now , struct timespec * sf_now ) {
4141 timespec_get (now , TIME_UTC );
42- sub_diff (now , & self -> start_time );
42+ * sf_now = * now ;
43+ sub_diff (sf_now , & self -> start_time );
4344}
4445
4546static PyObject * sonyflake_new (PyTypeObject * type , PyObject * args , PyObject * kwargs ) {
@@ -180,80 +181,80 @@ static void sonyflake_dealloc(struct sonyflake_state *self) {
180181 Py_DECREF (tp );
181182}
182183
183- static PyObject * sonyflake_sleep (PyObject * obj , struct timespec * to_nanosleep ) {
184- if (!obj ) {
184+ static PyObject * sonyflake_sleep (PyObject * obj , struct sonyflake_next_sleep_info * sleep_info ) {
185+ if (!( obj && sleep_info ) ) {
185186 return NULL ;
186187 }
187188
188- if (!to_nanosleep ) {
189- return obj ;
190- }
189+ struct timespec duration , now = sleep_info -> now ;
190+ int ret = 0 ;
191191
192- if ( to_nanosleep -> tv_sec == 0 && to_nanosleep -> tv_nsec == 0 ) {
193- return obj ;
194- }
192+ for (;; ) {
193+ duration = sleep_info -> future ;
194+ sub_diff ( & duration , & now );
195195
196- int ret = 0 ;
196+ if (duration .tv_sec == 0 && duration .tv_nsec == 0 ) {
197+ return obj ;
198+ }
197199
198- Py_BEGIN_ALLOW_THREADS ;
200+ Py_BEGIN_ALLOW_THREADS ;
199201#if __STDC_NO_THREADS__
200- ret = nanosleep (to_nanosleep , NULL );
202+ ret = nanosleep (& duration , NULL );
201203#else
202- ret = thrd_sleep (to_nanosleep , NULL );
204+ ret = thrd_sleep (& duration , NULL );
203205#endif
204- Py_END_ALLOW_THREADS ;
206+ Py_END_ALLOW_THREADS ;
205207
206- if (ret == 0 ) {
207- return obj ;
208- }
208+ if (ret == 0 ) {
209+ return obj ;
210+ }
209211
210- #if __STDC_NO_THREADS__
211- if (ret < 0 && errno == EINTR && PyErr_CheckSignals ()) {
212- goto err ;
213- }
212+ #if __STDC_NO_THREADS__ // nanosleep
213+ if (ret < 0 && errno == EINTR ) {
214214#else
215- if (ret == -1 ) {
216- if (PyErr_CheckSignals ()) {
217- goto err ;
215+ if (ret == -1 ) {
216+ #endif
217+ if (PyErr_CheckSignals ()) {
218+ goto err ;
219+ } else {
220+ timespec_get (& now , TIME_UTC );
221+ continue ;
222+ }
218223 }
219224
220- return obj ;
225+ break ;
221226 }
222- #endif
223227
224228 PyErr_SetFromErrno (PyExc_OSError );
225229err :
226230 Py_DECREF (obj );
227231 return NULL ;
228232}
229233
230- PyObject * sonyflake_next (struct sonyflake_state * self , struct timespec * to_nanosleep ) {
231- struct timespec now , future ;
234+ PyObject * sonyflake_next (struct sonyflake_state * self , struct sonyflake_next_sleep_info * sleep_info ) {
235+ struct timespec now , sf_now ;
232236 sonyflake_time current ;
233237 uint64_t sonyflake_id ;
234238
235239 PyThread_acquire_lock (self -> lock , 1 );
236240
237- get_relative_current_time (self , & now );
241+ get_relative_current_time (self , & now , & sf_now );
238242
239- current = to_sonyflake_time (& now );
240-
241- if (to_nanosleep ) {
242- to_nanosleep -> tv_sec = 0 ;
243- to_nanosleep -> tv_nsec = 0 ;
243+ if (sleep_info ) {
244+ sleep_info -> now = now ;
245+ sleep_info -> future = now ;
244246 }
245247
248+ current = to_sonyflake_time (& sf_now );
249+
246250 if (self -> elapsed_time < current ) {
247251 self -> elapsed_time = current ;
248252 self -> combined_sequence = 0 ;
249253 } else if (incr_combined_sequence (self )) {
250254 self -> elapsed_time ++ ;
251255
252- if (to_nanosleep ) {
253- from_sonyflake_time (self -> elapsed_time , & future );
254- sub_diff (& future , & now );
255-
256- * to_nanosleep = future ;
256+ if (sleep_info ) {
257+ from_sonyflake_time (& self -> start_time , self -> elapsed_time , & sleep_info -> future );
257258 }
258259 }
259260
@@ -264,7 +265,7 @@ PyObject *sonyflake_next(struct sonyflake_state *self, struct timespec *to_nanos
264265 return PyLong_FromUnsignedLongLong (sonyflake_id );
265266}
266267
267- PyObject * sonyflake_next_n (struct sonyflake_state * self , Py_ssize_t n , struct timespec * to_nanosleep ) {
268+ PyObject * sonyflake_next_n (struct sonyflake_state * self , Py_ssize_t n , struct sonyflake_next_sleep_info * sleep_info ) {
268269 assert (n > 0 );
269270
270271 PyObject * out = PyList_New (n );
@@ -273,14 +274,14 @@ PyObject *sonyflake_next_n(struct sonyflake_state *self, Py_ssize_t n, struct ti
273274 return NULL ;
274275 }
275276
276- struct timespec now , future ;
277- sonyflake_time current , diff ;
277+ struct timespec now , sf_now ;
278+ sonyflake_time current ;
278279
279280 PyThread_acquire_lock (self -> lock , 1 );
280281
281- get_relative_current_time (self , & now );
282+ get_relative_current_time (self , & now , & sf_now );
282283
283- current = to_sonyflake_time (& now );
284+ current = to_sonyflake_time (& sf_now );
284285
285286 if (self -> elapsed_time < current ) {
286287 self -> elapsed_time = current ;
@@ -299,28 +300,13 @@ PyObject *sonyflake_next_n(struct sonyflake_state *self, Py_ssize_t n, struct ti
299300 PyList_SetItem (out , i , PyLong_FromUnsignedLongLong (compose (self )));
300301 }
301302
302- if (!to_nanosleep ) {
303- goto end ;
304- }
305-
306- to_nanosleep -> tv_sec = 0 ;
307- to_nanosleep -> tv_nsec = 0 ;
308- diff = self -> elapsed_time - current ;
303+ PyThread_release_lock (self -> lock );
309304
310- if (diff <= 0 ) {
311- goto end ;
312- } else if (diff > 1 ) {
313- get_relative_current_time (self , & now );
305+ if (sleep_info ) {
306+ timespec_get (& sleep_info -> now , TIME_UTC );
307+ from_sonyflake_time (& self -> start_time , self -> elapsed_time , & sleep_info -> future );
314308 }
315309
316- from_sonyflake_time (self -> elapsed_time , & future );
317- sub_diff (& future , & now );
318-
319- * to_nanosleep = future ;
320-
321- end :
322- PyThread_release_lock (self -> lock );
323-
324310 return out ;
325311}
326312
@@ -375,10 +361,11 @@ static PyObject *sonyflake_repr(struct sonyflake_state *self) {
375361}
376362
377363static PyObject * sonyflake_iternext (struct sonyflake_state * self ) {
378- struct timespec to_nanosleep = { 0 , 0 };
379- PyObject * sonyflake_id = sonyflake_next (self , & to_nanosleep );
364+ struct sonyflake_next_sleep_info sleep_info ;
365+
366+ PyObject * sonyflake_id = sonyflake_next (self , & sleep_info );
380367
381- return sonyflake_sleep (sonyflake_id , & to_nanosleep );
368+ return sonyflake_sleep (sonyflake_id , & sleep_info );
382369}
383370
384371static PyObject * sonyflake_call (struct sonyflake_state * self , PyObject * args ) {
@@ -393,10 +380,10 @@ static PyObject *sonyflake_call(struct sonyflake_state *self, PyObject *args) {
393380 return NULL ;
394381 }
395382
396- struct timespec to_nanosleep = { 0 , 0 } ;
397- PyObject * sonyflake_ids = sonyflake_next_n (self , n , & to_nanosleep );
383+ struct sonyflake_next_sleep_info sleep_info ;
384+ PyObject * sonyflake_ids = sonyflake_next_n (self , n , & sleep_info );
398385
399- return sonyflake_sleep (sonyflake_ids , & to_nanosleep );
386+ return sonyflake_sleep (sonyflake_ids , & sleep_info );
400387}
401388
402389PyDoc_STRVAR (sonyflake_doc ,
0 commit comments