Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 213524
Collapse All | Expand All

(-)splashutils-1.5.3.4/src/daemon.c (-11 / +144 lines)
Lines 34-41 Link Here
34
pthread_mutex_t mtx_paint = PTHREAD_MUTEX_INITIALIZER;
34
pthread_mutex_t mtx_paint = PTHREAD_MUTEX_INITIALIZER;
35
pthread_mutex_t mtx_anim = PTHREAD_MUTEX_INITIALIZER;
35
pthread_mutex_t mtx_anim = PTHREAD_MUTEX_INITIALIZER;
36
pthread_cond_t  cnd_anim  = PTHREAD_COND_INITIALIZER;
36
pthread_cond_t  cnd_anim  = PTHREAD_COND_INITIALIZER;
37
pthread_mutex_t mtx_timeSkewCheck = PTHREAD_MUTEX_INITIALIZER;
37
38
38
pthread_t th_switchmon, th_sighandler, th_anim;
39
pthread_t th_switchmon, th_sighandler, th_anim, th_checkTime;
39
40
40
int ctty = CTTY_VERBOSE;
41
int ctty = CTTY_VERBOSE;
41
42
Lines 58-64 Link Here
58
/* A container for the original settings of the silent TTY. */
59
/* A container for the original settings of the silent TTY. */
59
struct termios tios;
60
struct termios tios;
60
61
62
/* Flag set by the checkTime thread. Locked by mtx_timeSkewCheck. */
63
bool timeSkewDetected_b = false;
64
61
#if WANT_MNG
65
#if WANT_MNG
66
67
/*
68
 * Check for time skews.
69
 */
70
void *thf_checkTime(void *unused)
71
{
72
    struct timeval        tv_current;
73
    const  unsigned long  sleepTime_ui = 100 * 1000;  // 100 msecs
74
    long                  lastMsec;
75
    long                  currentMsec;
76
    long                  diffMsec;
77
78
79
    /* Try to detect system clock changed */
80
    if ( gettimeofday( &tv_current, NULL ) != 0)
81
    {
82
        perror( "Can't get time with gettimeofday!" );
83
        return 0;
84
    }
85
    
86
    lastMsec = ( ( (long) tv_current.tv_sec ) * ( (long) 1000 ) ) +
87
        ( ( (long) tv_current.tv_usec ) / ( (long) 1000 ) );
88
    usleep( sleepTime_ui );
89
90
91
    while ( 1 )
92
    {
93
        gettimeofday( &tv_current, NULL );
94
        currentMsec = ( ( (long) tv_current.tv_sec ) * ( (long) 1000 ) ) +
95
            ( ( (long) tv_current.tv_usec ) / ( (long) 1000 ) );
96
        
97
        diffMsec = currentMsec - lastMsec;
98
99
        if ( ( diffMsec < 0 ) || ( diffMsec > 10*sleepTime_ui ) )
100
        {
101
            /* Time skew detected! Signal thf_anim a reset. */
102
            pthread_mutex_lock( &mtx_timeSkewCheck );
103
            timeSkewDetected_b = true;
104
            pthread_mutex_unlock( &mtx_timeSkewCheck );
105
106
            pthread_mutex_lock(&mtx_anim);
107
            pthread_cond_signal(&cnd_anim);
108
            pthread_mutex_unlock(&mtx_anim);
109
110
            /* Get time again to compensate for delays caused by the mutex stuff. */
111
            gettimeofday( &tv_current, NULL );
112
            currentMsec = ( ( (long) tv_current.tv_sec ) * ( (long) 1000 ) ) +
113
                ( ( (long) tv_current.tv_usec ) / ( (long) 1000 ) );
114
        }
115
        
116
        lastMsec = currentMsec;
117
        usleep( sleepTime_ui );
118
    }
119
120
    return 0;
121
}
122
123
62
/*
124
/*
63
 * Display all animations of the type 'once' or 'loop'.
125
 * Display all animations of the type 'once' or 'loop'.
64
 */
126
 */
Lines 69-86 Link Here
69
	item *i;
131
	item *i;
70
	mng_anim *mng;
132
	mng_anim *mng;
71
	int delay = 10000, rdelay, oldstate;
133
	int delay = 10000, rdelay, oldstate;
72
	struct timespec ts, tsc;
134
	struct timespec    ts, ts_last;
135
        bool               resetAnims_b = false;
136
137
        /* Initialize the time value. */
138
        clock_gettime(CLOCK_REALTIME, &ts);
139
        ts_last = ts;
73
140
74
	while(1) {
141
	while(1) {
142
                /* Check for a time skew */
75
		pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldstate);
143
		pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldstate);
76
		pthread_mutex_lock(&mtx_paint);
144
                pthread_mutex_lock( &mtx_timeSkewCheck );
145
                resetAnims_b       = timeSkewDetected_b;
146
                timeSkewDetected_b = false;
147
                pthread_mutex_unlock( &mtx_timeSkewCheck );
148
		pthread_setcancelstate(oldstate, NULL);
149
150
151
                /* Reset animations if neccessary */
152
                if ( resetAnims_b )
153
                {
154
                    pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldstate);
155
                    pthread_mutex_lock(&mtx_paint);
156
157
                    for (i = theme->anims.head; i != NULL; i = i->next) {
158
			ca = i->p;
159
                        co = container_of(ca);
160
161
			if (!co->visible ||
162
                            (ca->flags & F_ANIM_METHOD_MASK) == F_ANIM_PROPORTIONAL ||
163
			    ca->status == F_ANIM_STATUS_DONE)
164
                            continue;
165
166
			mng = mng_get_userdata(ca->mng);
167
168
                        if ( (!mng->displayed_first) || (mng->wait_msecs > 0) )
169
                            mng_display_restart(ca->mng);
170
                    }
171
                    pthread_mutex_unlock(&mtx_paint);
172
                    pthread_setcancelstate(oldstate, NULL);
173
174
                    /* Our times are not valid any more. */
175
                    clock_gettime(CLOCK_REALTIME, &ts_last);                    
176
                }
177
178
77
		/* Find the shortest delay. */
179
		/* Find the shortest delay. */
180
		pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldstate);
181
		pthread_mutex_lock(&mtx_paint);
78
		for (i = theme->anims.head; i != NULL; i = i->next) {
182
		for (i = theme->anims.head; i != NULL; i = i->next) {
79
			ca = i->p;
183
			ca = i->p;
80
			co = container_of(ca);
184
			co = container_of(ca);
81
185
82
			if (!co->visible ||
186
			if (!co->visible ||
83
				(ca->flags & F_ANIM_METHOD_MASK) == F_ANIM_PROPORTIONAL ||
187
                            (ca->flags & F_ANIM_METHOD_MASK) == F_ANIM_PROPORTIONAL ||
84
			    ca->status == F_ANIM_STATUS_DONE)
188
			    ca->status == F_ANIM_STATUS_DONE)
85
				continue;
189
				continue;
86
190
Lines 89-112 Link Here
89
			/* If this is a new animation (activated by a service),
193
			/* If this is a new animation (activated by a service),
90
			 * display it immediately. */
194
			 * display it immediately. */
91
			if (!mng->displayed_first) {
195
			if (!mng->displayed_first) {
196
                            /* Set delay to 0 and paint the complete screen later. */
197
                            delay = 0;
198
#if 0
92
				anim_render_canvas(ca);
199
				anim_render_canvas(ca);
93
200
94
				if (ctty == CTTY_SILENT)
201
				if (ctty == CTTY_SILENT)
95
					fbsplashr_render_screen(theme, true, false, FBSPL_EFF_NONE);
202
                                    fbsplashr_render_screen(theme, true, false, FBSPL_EFF_NONE);
203
#endif
96
			}
204
			}
97
205
98
			if (mng->wait_msecs < delay && mng->wait_msecs > 0) {
206
			if (mng->wait_msecs < delay && mng->wait_msecs > 0) {
99
				delay = mng->wait_msecs;
207
                            delay = mng->wait_msecs;
100
			}
208
			}
101
		}
209
		}
102
		pthread_mutex_unlock(&mtx_paint);
210
		pthread_mutex_unlock(&mtx_paint);
103
		pthread_setcancelstate(oldstate, NULL);
211
		pthread_setcancelstate(oldstate, NULL);
104
212
213
214
                /* Get the current time and calculate the delay until the next refresh. */
105
		pthread_mutex_lock(&mtx_anim);
215
		pthread_mutex_lock(&mtx_anim);
106
		clock_gettime(CLOCK_REALTIME, &ts);
216
		clock_gettime(CLOCK_REALTIME, &ts);
107
217
108
		ts.tv_sec  += (int)(delay / 1000);
218
109
		ts.tv_nsec += (delay % 1000) * 1000000;
219
                /* Time we spent between the last update of the anim delays
220
                 * and now (ts - ts_last) is subtracted from the delay.
221
                 */
222
		ts.tv_sec  += (int)(delay / 1000)      - (ts.tv_sec  - ts_last.tv_sec);
223
		ts.tv_nsec += (delay % 1000) * 1000000 - (ts.tv_nsec - ts_last.tv_nsec);
110
224
111
		/* Check for overflow of the nanoseconds field */
225
		/* Check for overflow of the nanoseconds field */
112
		if (ts.tv_nsec >= 1000000000) {
226
		if (ts.tv_nsec >= 1000000000) {
Lines 114-132 Link Here
114
			ts.tv_nsec -= 1000000000;
228
			ts.tv_nsec -= 1000000000;
115
		}
229
		}
116
230
231
                /* Wait until signaled or timeout */
117
		pthread_cond_timedwait(&cnd_anim, &mtx_anim, &ts);
232
		pthread_cond_timedwait(&cnd_anim, &mtx_anim, &ts);
118
		pthread_mutex_unlock(&mtx_anim);
233
		pthread_mutex_unlock(&mtx_anim);
119
234
120
		pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldstate);
235
		pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldstate);
121
		pthread_mutex_lock(&mtx_paint);
236
		pthread_mutex_lock(&mtx_paint);
237
238
122
		/* Don't paint anything if we aren't in silent mode. */
239
		/* Don't paint anything if we aren't in silent mode. */
123
		if (ctty != CTTY_SILENT)
240
		if (ctty != CTTY_SILENT)
124
			goto next;
241
			goto next;
125
242
243
126
		/* Calculate the real delay. We might have been signalled by
244
		/* Calculate the real delay. We might have been signalled by
127
		 * the splash daemon before 'delay' msecs passed. */
245
		 * the splash daemon before 'delay' msecs passed. */
128
		clock_gettime(CLOCK_REALTIME, &tsc);
246
		clock_gettime(CLOCK_REALTIME, &ts);
129
		rdelay = delay + (tsc.tv_sec - ts.tv_sec)*1000 + (tsc.tv_nsec - ts.tv_nsec)/1000000;
247
		rdelay = delay + (ts.tv_sec - ts_last.tv_sec)*1000 + (ts.tv_nsec - ts_last.tv_nsec)/1000000;
130
248
131
		/* Update the wait time for all relevant animation objects. */
249
		/* Update the wait time for all relevant animation objects. */
132
		for (i = theme->anims.head ; i != NULL; i = i->next) {
250
		for (i = theme->anims.head ; i != NULL; i = i->next) {
Lines 138-143 Link Here
138
				continue;
256
				continue;
139
257
140
			mng = mng_get_userdata(ca->mng);
258
			mng = mng_get_userdata(ca->mng);
259
260
                        /* Display new anims right now. */
261
                        if (!mng->displayed_first)
262
                        {
263
                            anim_render_canvas(ca);
264
                        }
265
                        
141
			if (mng->wait_msecs > 0) {
266
			if (mng->wait_msecs > 0) {
142
				mng->wait_msecs -= rdelay;
267
				mng->wait_msecs -= rdelay;
143
				if (mng->wait_msecs <= 0)
268
				if (mng->wait_msecs <= 0)
Lines 146-152 Link Here
146
		}
271
		}
147
		fbsplashr_render_screen(theme, true, false, FBSPL_EFF_NONE);
272
		fbsplashr_render_screen(theme, true, false, FBSPL_EFF_NONE);
148
273
149
next:	pthread_mutex_unlock(&mtx_paint);
274
275
next:	
276
                /* Save the time just before refreshing the wait_msecs fields. */
277
                ts_last = ts;
278
                
279
                pthread_mutex_unlock(&mtx_paint);
150
		pthread_setcancelstate(oldstate, NULL);
280
		pthread_setcancelstate(oldstate, NULL);
151
281
152
		/* Default delay is 10s */
282
		/* Default delay is 10s */
Lines 560-565 Link Here
560
#ifdef CONFIG_MNG
690
#ifdef CONFIG_MNG
561
	/* Start the animation thread */
691
	/* Start the animation thread */
562
	pthread_create(&th_anim, NULL, &thf_anim, NULL);
692
	pthread_create(&th_anim, NULL, &thf_anim, NULL);
693
694
        /* Start the time skew check thread */
695
        pthread_create(&th_checkTime, NULL, &thf_checkTime, NULL );
563
#endif
696
#endif
564
697
565
	pthread_mutex_lock(&mtx_tty);
698
	pthread_mutex_lock(&mtx_tty);

Return to bug 213524