Question

I have been hacking on the code for Xournal in order to add auto-save functionality. My initial implementation was very dumb: every 60 or so seconds, do a save. The feature ostensibly works.

However, after testing it out for a while, I've noticed that when auto-save runs, the application temporarily freezes up, which is quite annoying if you're in the middle of a pen stroke. I'm trying to figure out how to fix this.

One possibility I've thought up of is for autosave to check whether or not the pen is touching the screen before autosaving; if it is touched, attach a one time only callback scheduled for a second after the pen is lifted. (if the same thing happens, repeat). Another possibility would be to optimize the save function sufficiently such that there is no gap (seems unlikely).

Anyone have any suggestions about this? Xournal uses the Gnome/GTK toolkit, and is written in C.

Update: I implemented the anti-clobber logic, and I'm very happy with the resulting autosave granularity and performance. One of those times threads are (thankfully) not necessary! Thanks all for your suggestions.

Was it helpful?

Solution

If the UI freezes for any noticeable period of time, a separate thread is probably the way to go. If the only reason you're noticing the UI freeze is because you happen to be writing at the time and the interruption is only very brief, then your method might work. Your fix is probably way easier than creating another thread, so try that first.

If you do end up using threads, go with g_threads instead of pthreads since you're using GTK+. They'll be more portable.

OTHER TIPS

While I would agree using threads is a "correct" textbox answer, it's not always the way you have to do things. Multithreading tends to bring up tons of issues if you're not careful -- the main one here probably being locking access to the data during the autosave. Then if the main thread enters a wait to access the data, you're right back where you started. So then you create a queue of pending changes or something, and you lose track of what's going on. Depending on how complex the underlying data structures are, making a copy could also freeze the main thread.

Anyways point being, I would try your first option. It's quick, simple, and to the point, and I don't see why it wouldn't work.

(Note: I haven't looked under the hood of Xournal so take this with a grain of salt. Or a salt shaker. Or something)

Can you push the autosave functionality to a separate thread? By running on a second thread you would be able to run the save in parallel with the gui and would avoid the freezing window.

I've got very little experience with c, but I would think this site could help.

I've had a similar situation in the past and here's the way I solved it (.Net):

  1. Background timer ticks at x second intervals
  2. On the tick, disable the timer and handle the appropriate event.
  3. In the event handler, save and enable the timer.

The only flaw we've seen actually happen was someone killing the app before the event handler is called and losing 1 minute's worth of work.

How about this?

Use the callback idea but have it run every 10 inputs in addition to every 60 seconds. With a time-based autosave, there's a problem that the amount of stuff that gets lost is proportional to how fast the user can work.

If you want to go a step further, have it save a partial undo log to disk after every change in addition to the full save. That way, the worst thing that can happen from a crash is losing the last input stroke.

My focus is to use an hipervisor thread comparing via some hash algorithm the file contents every N secs on change event then notify to the parent thread and callback the autosave function.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top