Share the world...
We are all The ONE and The ONE is all.
SOLAR OS and Private Variables |
---|
In Sol the exact same code is executed for each new instance of an application. Even more all app defined global variables (at compile time) are also shared (curently). This makes thing very simple as all applications can intercomunicate via global variables or memory zones. The API is very fast and easy to call because of this also.
Of course LOCAL variables are not shared since they are created on stack at each code execution.
I have choosen the optimistic side considering that:
Will bring greater benefits than keeping application inside an protective golden cage of fears.
But Every Choice has its consequences...
This choice raises the problem of global variables that are not shared.
For example an application might need a private counter for how many times its client area was clicked. If this variable is simply defined as:
my_counter dd 0
And then, on the ACT_LEFT_UP_CHILD message on application's callback:
My_App_Callback PROC STDCALL USES ebx,ecx,edx,esi,edi ARG @@wnd_handle:DWORD,@@wnd_action:DWORD,@@wnd_param1:DWORD,@@wnd_param2:DWORD ;-------------------------------------- ; a case based on message/event value ;-------------------------------------- .IF [@@wnd_action]==ACT_LEFT_UP_CHILD inc [my_counter] .ENDIF xor eax,eax ret ENDP
Then all instances of the application will increment the same variable and this might not be what we intended (but sometime is).
Basically we need a method of having variables that are private (specific) to each instance of an application.
If the size of variables is smaller then use the space proviced in sol_window structure. This works for approximative 32 dwords and is the fastest and most simple solution. As a new window structure is alocated at each window creation this space is private to each instance.
The Small Sample application uses this method to store the click counter in window_data01.
If the size of your variables is greater or can grow greater then you can dynamically allocate memory on the application initialization phase and store pointer to this private data zones in the window_data01... variables.
The memory alocated there should be dealocated on ACT_CLOSE_CHILD message.
HDD FAT32 explorer and DebugView applications use this method.
One Solution is to add relocation to your application and in the application init phase copy the base code to another location and fix the relocations yourself.
Disadvantages:
Create a new set of selectors for the application and make it believe it will run at the same address all the time. This avoids relocations but since the application uses different selectors than the kernel, a new method of calling the API is required.
This will also need Callgates for calling all and any of the OS API/functions.
This looks like a good idea for a development environment because if this application has a crash, theoretically it will not crash the whole system also. Because of the cooperative nature of SOLAR OS multitasking a watchdog of some kind shoulf be installed on IRQ-0 also...
Disadvantages:
This sample code ilustrates how an application could define and initialize private variables.
;------------------------------------------ ;define this structure for easy acces to ;private variables ;------------------------------------------ My_App_Private_Vars STRUC my_strings_count dword ? my_strings_mem_handle dword ? my_strings_lp dword ? ENDS ... ;init this application instance ;--------------------------------------------- ; get access to windows's private data ; since we need each instance ; to have it's own variables ;--------------------------------------------- Call API_Window_Get_Addr_Private STDCALL,[@@wnd_handle] mov edi,eax mov [edi.my_strings_count],-1 ;no strings ;----------------------------- ; alloc some memory ;----------------------------- Call API_Memory_Alocate,1 ;get 4k for start mov [edi.my_strings_mem_handle],eax ;store handle as we need it for Release mov [edi.my_strings_lp],esi ;store pointer ...