On Sun, 22 Jun 2008, Julien BLACHE wrote: [ . . . ] > Anything in the option descriptor can change after the backend tells > the frontend to reload the options, and I think that's what you're > seeing with gdb when the net backend refreshes the option > descriptors. But the memory allocated by sanei_wire for the option > descriptors and their content should not get overwritten unless > there's been a call to sane_get_option_descriptor(). > > The code flow looks roughly like this: > > frontend calls sane_get_option_descriptor() for first option > net backend loads option descriptors (fetch_options()) > frontend calls sane_get_option_descriptor() a few more times to load all > options > frontend sets an option value by calling sane_control_option() > net backend forwards to underlying backend > underlying backend replies with info containing SANE_INFO_RELOAD_OPTIONS > net backends marks local copy as invalid, forwards to frontend > frontend calls sane_get_option_descriptor() for first option > net backend loads option descriptors (fetch_options()) > frontend calls sane_get_option_descriptor() a few more times to reload all > the options
I've been trying to understand the net backend code this evening. I see where fetch_options() iterates over the option list and makes a local copy in net.c: memcpy (s->local_opt.desc[option_number], s->opt.desc[option_number], sizeof (SANE_Option_Descriptor)); However, this memcpy does not duplicate the .constraint member of the associated SANE_Option_Descriptor. It copies the pointer stored in the opt.desc structure but not the underlying data. The sanei_w_* code still confuses me a bit, but doesn't fetch_options() clear s->opt right near the top of the function? I'm looking at sanei_w_set_dir (&s->hw->wire, WIRE_FREE); s->hw->wire.status = 0; sanei_w_option_descriptor_array (&s->hw->wire, &s->opt); Drilling into this last function we get to sanei_w_array() where the memory associated with s->opt[] gets free()'d. Now the pointer that was stored in menu_item[0].label = s->local_opt.desc[44].string_list[0] = s->opt.desc[44].string_list[0] but that memory just been deallocated. The menu will still work correctly if that memory is left untouched, or if s->opt happens to be restored exactly as it was when the menu was initially constructed. (And if it's the latter, why bother making the local copy in the first place?) What is the intent of duplicating s->opt into s->local_opt? If it is to provide a stable local version of the scanner descriptors then shouldn't the .constraint union (*string_list, *word_list, or *range) be duplicated as well? -- Brad -- To UNSUBSCRIBE, email to [EMAIL PROTECTED] with a subject of "unsubscribe". Trouble? Contact [EMAIL PROTECTED]