wc WNDCLASSEX <sizeof wc, NULL, \
offset WndProc, 0, 0, 0, \
0, 0, COLOR_WINDOW+1, 0, \
offset ClassName, 0>
.data
note1 NOTIFYICONDATA <sizeof NOTIFYICONDATA, 0, IDI_TRAY, \
NIF_ICON+NIF_MESSAGE+NIF_TIP, WM_SHELLNOTIFY, 0,
db 'AppName',0
0,0,\
TCHAR[256], 0, TCHAR[64], 0, 0>
(http://smiles.kolobok.us/big_standart/scratch_one-s_head.gif)
Quote from: bomz on July 01, 2011, 08:34:33 PM
.data
note1 NOTIFYICONDATA <sizeof NOTIFYICONDATA, 0, IDI_TRAY, \
NIF_ICON+NIF_MESSAGE+NIF_TIP, WM_SHELLNOTIFY, 0,
db 'AppName'>
Windows.inc:
NOTIFYICONDATAA STRUCT
cbSize DWORD ?
hwnd DWORD ?
uID DWORD ?
uFlags DWORD ?
uCallbackMessage DWORD ?
hIcon DWORD ?
szTip BYTE 64 dup (?)
NOTIFYICONDATAA ENDS
typedef struct _NOTIFYICONDATA {
DWORD cbSize;
HWND hWnd;
UINT uID;
UINT uFlags;
UINT uCallbackMessage;
HICON hIcon;
TCHAR szTip[64];
DWORD dwState;
DWORD dwStateMask;
TCHAR szInfo[256];
union {
UINT uTimeout;
UINT uVersion;
};
TCHAR szInfoTitle[64];
DWORD dwInfoFlags;
GUID guidItem;
HICON hBalloonIcon;
} NOTIFYICONDATA, *PNOTIFYICONDATA;
http://msdn.microsoft.com/en-us/library/bb773352%28v=vs.85%29.aspx
I saw here. My mistake
(http://xmages.net/storage/10/1/0/e/9/upload/e039f9a1.png)
note NOTIFYICONDATA <sizeof NOTIFYICONDATA, 0, IDI_TRAY, \
NIF_ICON+NIF_MESSAGE+NIF_TIP, WM_SHELLNOTIFY, 0, \
'ClipBoard'>
(http://smiles.kolobok.us/big_standart/greeting.gif)
Sometimes Windows.inc contains a simpler structure version, compatible with older OS versions such as Win 98 or Win 2000.
The cbSize member allows the newer Windows versions to recognise how to treat the structure, and to apply e.g. default values to new members that are not present in the legacy version.
(http://smiles.kolobok.us/light_skin/thank_you2.gif)
I am making hard optimizing of code
Quote from: bomz on July 01, 2011, 09:22:11 PM
I am making hard optimizing of code
sry to say, but this optimization is sensless and may be also dangerous ::)
(BTW: it is a very bad idea to combine (style-)flags using '+')
+ no equal OR? I use + for economy places in string
dangerous? (http://smiles.kolobok.us/light_skin/girl_impossible.gif)
what sence in fill structure inside code?
Quote from: bomz on July 01, 2011, 09:42:38 PM
+ no equal OR?
0101y or 0100y = 0101y
0101y + 0100y = 1001y
Quote from: bomz on July 01, 2011, 09:44:56 PM
dangerous? (http://smiles.kolobok.us/light_skin/girl_impossible.gif)
what sence in fill structure inside code?
it is not thread save - there is no problem, as long as not using this structure from more than one thread.
what difference if I use one variable in two threads I fill it in code or in data?
Quote from: bomz on July 01, 2011, 09:59:54 PM
what difference if I use one variable in two threads I fill it in code or in data?
Actually, it is "thread safer" in the .code section because it will be read-only anyway...
wc WNDCLASSEX <sizeof wc, NULL, \
offset WndProc, 0, 0, 0, \
0, 0, COLOR_WINDOW+1, 0, \
offset ClassName, 0>
note NOTIFYICONDATA <sizeof NOTIFYICONDATA, 0, IDI_TRAY, \
NIF_ICON+NIF_MESSAGE+NIF_TIP, WM_SHELLNOTIFY, 0, \
'ClipBoard'>
ofn OPENFILENAME <sizeof OPENFILENAME, 0, 0, offset FileFilter,\
0, 0, 0, offset SaveAs, MAX_PATH, 0, 0, 0, offset AppName, \
OFN_PATHMUSTEXIST OR OFN_LONGNAMES OR OFN_EXPLORER OR OFN_HIDEREADONLY OR OFN_OVERWRITEPROMPT,\
0, 0, 0, 0, 0, 0>
findtext FINDREPLACE <sizeof FINDREPLACE, 0, 0, \
FR_FINDNEXT+FR_HIDEWHOLEWORD+FR_DOWN+FR_DIALOGTERM,\
offset FindBuffer, 0, sizeof FindBuffer, 0, 0, 0, \
offset AppName>
shellinfo SHELLEXECUTEINFO <sizeof shellinfo, 40h, 0, offset edit, \
offset EditFile, 0, 0, 1, 0, 0, 0, 0, 0>
EDITOR GUITHREADINFO < sizeof GUITHREADINFO, 0, 0, 0, 0, 0, 0, 0, <0, 0> >
This do - all works
read only if you do so:
jmp @F
string db 'kolbasa-seledka',0
@@:
This String you can't change. Ypu may use it only in code under this strings
it is simple: make all variables and structures local - then it is clearly thread save. By doing this, you application will also benefits from the fact, that the current stackspace/location is properly completely hold in the cache.
if I do all variables local I must fill it fully including zero's it need about 50 strings of code
Quote from: bomz on July 01, 2011, 10:12:13 PM
if I do all variables local I must fill it fully including zero's it need about 50 strings of code
if thread save code is needed,
then you must do it.
Quote from: bomz on July 01, 2011, 10:12:13 PM
if I do all variables local I must fill it fully including zero's it need about 50 strings of code
Yes, but you could have a 'template' in .data from which you copy your stuff into the locals. Watch the order, though. By the way, I can't quite see the point why code must be thread-safe all the time. Only on very rare occasions would I start a separate thread using the same data structures in parallel.
if you need two threads you need have local data for each. this structeres which I move to data use only in one place and each time call it they begin FILL
in this program with ListBox I am many times in different places of code put/get data from list view and each time begin
mov lvi.imask,LVIF_TEXT+LVIF_PARAM
mov lvi.iItem, esi
mov lvi.iSubItem,0
lea eax, buffer
mov lvi.pszText, eax
mov lvi.lParam, esi
invoke SendMessage, hList, LVM_INSERTITEM, 0, addr lvi
this is the half of code. and I want to all such places make it own variable and fill it in data
Quote from: jj2007 on July 01, 2011, 10:31:45 PMI can't quite see the point why code must be thread-safe all the time.
It must not be thread save all the time - only when needed :wink
However, generally it is an good approach to create only thread save code (IMO) - especially when writing libraries/DLLs.
BTW jj: is MasmBasic thread save?
else - to exlude the conflict between diferent places of code which may read/write listview, I need do many proc's with it's own local LVI buffer - this need push/pop call/back.....
Quote from: qWord on July 01, 2011, 10:42:50 PM
BTW jj: is MasmBasic thread save?
If you know what you are doing, sure. But it uses lots of global variables, of course. For example, if you create two threads that write in parallel to the console, you'll be in trouble... how do you use parallel threads?
not all data needs to be local
generally, it is only the variables that are written to that can cause trouble
Quote from: jj2007 on July 02, 2011, 05:45:29 AMIf you know what you are doing, sure. But it uses lots of global variables, of course
IMO, if is not documented, it is a really strong contra argument for using MasmBasic (?)
Quote from: jj2007 on July 02, 2011, 05:45:29 AMhow do you use parallel threads?
mainly for data processing, but sometimes also for GUI threads...
Quote from: dedndave on July 02, 2011, 11:52:39 AM
not all data needs to be local
generally, it is only the variables that are written to that can cause trouble
the ideal 'thread save' program/library has only a const-section, no data section :bg
It is a problem if the procedure needs to be re-entrant, you can use global scope variables in non critical operations if you don't mind tracking the globals but for re-entrant code you basically need a structure that holds all of the data you need and you pass its address to any dependencies that need that data. It is actiually a very efficient technique as you only need to pass the structure address so the stack overhead is very low and it is fast.
Quote from: qWord on July 02, 2011, 12:53:32 PM
Quote from: dedndave on July 02, 2011, 11:52:39 AM
not all data needs to be local
generally, it is only the variables that are written to that can cause trouble
the ideal 'thread save' program/library has only a const-section, no data section :bg
Most of the global variables are read-only, like CrLf$ etc, but there are also many writeable ones, such as the structures that serve the Dim engine. However, even if you create A$(100) in thread A and B$(100) in thread B, they will never collide. There are some temporary general purpose buffers, such as for the deb macro, but even that should not cause trouble in any real life situations.
Of course, with a lot of acrobatic efforts, one could make a library with 100+ functions 'theoretically' thread-safe. But first, there are good reasons why I sometimes use global variables, and second, what for? If I really need a second thread, it's for performance reasons, so that is typically a highly optimised group of hand-crafted loops in which you would never use something as slow as a console print (not thread-safe) or string concatenation with Let - not thread-safe in theory, but in real life, you might find it very difficult to construct a conflict situation where two Let My$=Str$(eax) happen at exactly the same moment and draw on the common circular buffer used by Str$() and many other string functions.
So in short: If you are really scared about thread safety, 1. do not create threads, 2. if you have to, don't use MB functions in them, or 3., if you are paranoically scared, don't use MasmBasic for those proggies that require extra threads.
Quote from: jj2007 on July 02, 2011, 04:01:38 PM[...] but even that should not cause trouble in any real life situations.
in real life application it can and it does happen.
Quote from: jj2007 on July 02, 2011, 04:01:38 PMOf course, with a lot of acrobatic efforts, one could make a library with 100+ functions 'theoretically' thread-safe
it is very easy to create thread save: do not use globals. Sure, using Assmbler it is a bit more work than in c/c++, but it is doable.
Quote from: jj2007 on July 02, 2011, 04:01:38 PMSo in short: If you are really scared about thread safety, 1. do not create threads, 2. if you have to, don't use MB functions in them, or 3., if you are paranoically scared, don't use MasmBasic for those proggies that require extra threads.
sry jj, I won't attack you!
However, some time back I've such problems while creating a DLL for Labview (for reading 1-wire temperature sensors) - my luck, I've discovert that bug while running a test some hours. It was cause by wrapper function for file I/O, that uses a static variable ...
Quote from: qWord on July 02, 2011, 04:45:01 PM
it is very easy to create thread save: do not use globals....
sry jj, I won't attack you!
Hi qWord,
I hope you understand my little dilemma:
- if I say MB is thread-safe, somebody will find an occasion to call me a liar;
- if I say it's not thread-safe, those noobs that could profit from having a simple HLL
inside assembly will read it's not
thread-safe...
The truth is that MasmBasic is not Basic, it's
assembler - otherwise ml.exe or Jwasm.exe could not assemble a MB source. And although it's astonishingly fool-proof, an ambitious programmer will be able to produce a GPF. But you need to do really senseless things, such as
main thread:
Open "O", #1, "MyThreadA.txt"
2nd thread:
Open "I", #1, "MyThreadB.txt"
Believe me there will be problems (the handles table is global, and nope, I won't change that). But there won't be any problems if you "sensibly" use #2 in thread #2. Knowing all the inner structure of MB by heart, I might be able to construct some situations where a multi-threaded MB app crashes, but why stress myself intellectually if I can achieve the same "result" with a simple xor edx, edx - div edx? Long live assembler!
There is a big circular buffer that allows e.g. Print Str$(ebx), "=", Hex$(ebx), "=", Bin$(ebx), CrLf$ - but it could cause trouble if two threads decide to do a Print operation in exactly the same nanosecond. A mad programmer can achieve that on purpose, a sensible programmer or a noob would not be able to do such nonsense.
There are a handful of global vars shared between threads, such as file handles and array handles. They won't do any harm to each other but having them in global variables means that you can indeed read in a string array in thread A and use it in thread B. This is
by design.
:bg
Quote from: jj2007 on July 02, 2011, 06:53:01 PM
"but why stress myself intellectually"
.... Said the assembly programmer
You can write thread safe OR thread unsafe code in masm like anything else, it depends entirely on what you want to write. There is no point in all code or a given development environment being fully thread safe as a vast number of tasks don't require it. Where you need re-entrant code, you write it accordingly and maintain the appropriate data structures on a per thread basis or you can mess around with thread local storage if you like but it comes back to what YOU write, not the development environment that you write it in.