Hi Joursoir

On Fri, 2022-04-01 at 22:43 +0300, Joursoir wrote:
Hello Thomas,

I went ahead and started looking into shutdown functions. 
Gread that you've already looked so deep into the problem. Over that, plese don't forget the other importent tasks at https://www.flashrom.org/GSoC to make a successfull application for GSoC.
Almost of
them use global variables, but I already have ideas on how to rewrite
it. Now I start coding a prototype and want to implement struct
example_data. But I have run into a problem with its initialization:

1) In theory, we can declare a static variable within each programmer's
file. It would be convenient, but this method has a big disadvantage.
We allocate private_data for every programmers but use only one.
Yes. Also this would keep the global state at the same place.

2) It's not possible to add a variable to struct programmer_entry
because the structure is read only (structures in programmer.h are
declared as const)
This could be possible. When converting `static const struct programmer_entry *programmer` from flashrom.c into `struct programmer_entry` and copying the function pointer from the selected progtrammer.
Beside that, there is `flashrom_programmer` in the libflashrom api which is currently an unused placeholder. This could used to hold the programmer_entry and the data.
3) Use a static global variable in flashrom.c. Lesser of two evils
principle as they say

static const struct programmer_entry *programmer = NULL;
static const char *programmer_param = NULL;
static void *programmer_data = NULL;
This is the easiest version and would also the variant I would begin with.

The next issue is the initialization of programmer_data:

a) Do it inside programmer->init(). The problem here is the duplication
of programmer_data init code in each function.

b) Do it outside programmer->init(). The problem here is that we can't
find out the size of example_data (it can be drkaised_data,
it85spi_data and etc)

programmer_data = calloc(1, sizeof(EXAMPLE_DATA));
if (!data) {
        ...
}
...
ret = programmer->init(&programmer_data);
Since the programmer data is unique to each programmer it can only be initialized in that programmer init code.
The location of the programmer data can be hand over to the init function.
`programmer_init(void **data);` and the called like `programmer->init(&programmer_data);

Perhaps there is some simpler solution, but I don't notice it.

I hope this answers your questions enough. Otherwise please ask again.

--Thomas