When I call GetCurrentThreadId, is there a reserved value that will never be used for a thread-id, maybe zero ? I want to get the thread-id directly from the TIB and I need a reserved value. Otherwise I'd use a additional bool.
Thread ID of a valid thread is always non-zero. See Thread Handles and Identifiers which states:
Note that no thread identifier will ever be 0.
Related
I'm using the libwebsockets v2.4.
The doc seems unclear to me about what I have to do with the returned value of the lws_write() function.
If it returns -1, it's an error and I'm invited to close the connection. That's fine for me.
But when it returns a value that is strictly inferior to the buffer length I pass, should I consider that I have to write the last bytes that could not be written later (in another WRITABLE callback occurrence). Is it even possible to have this situation?
Also, should I use the lws_send_pipe_choked() before using the lws_write(), considering that I always use lws_write() in the context of a WRITABLE callback?
My understanding is that lws_write always return the asked buffer length except is an error occurs.
If you look at lws_issue_raw() (from which the result is returned by lws_write()) in output.c (https://github.com/warmcat/libwebsockets/blob/v2.4.0/lib/output.c#L157), you can see that if the length written by lws_ssl_capable_write() is less than the provided length, then the lws allocate a buffer to fill up the remaining bytes on wsi->trunc_alloc, in order for it to be sent in the future.
Concerning your second question, I think it is safe to call lws_write() in the context of a WRITABLE callback without checking if the pipe is choked. However, if you happen to loop on lws_write() in the callback, lws_send_pipe_choked() must be called in order to protect the subsequent calls to lws_write(). If you don't, you might stumble upon this assertion https://github.com/warmcat/libwebsockets/blob/v2.4.0/lib/output.c#L83 and the usercode will crash.
This function is used for attaching allocated memory segment to the calling process. It takes three arguments. First argument corresponds to identifier of memory segment. Second argument is pointer to memory segment. For second argument, NULL or 0 value is passed to the function, since when we allocate the shared memory, we know only its identifier not its memory address.
However, I cannot find what the task of third argument is. Some codes that I am encountered by set the flag value to 0. NULL and 0 have same meaning in C language, and I think that additional adjustments are not needed; hence, NULL is passed to the function as third argument.
Is there anyone who can explain the task of flag value in shmat() function ?
Four flags are defined:
SHM_RDONLY - the segment is attached for reading; default is Read/Write
SHM_RND - the attach occurrs at the address equal to shmaddr rounded down to the nearest multiple of SHMLBA (usually defined as the page size)
SHM_REMAP - flag may be specified in shmflg to indicate that the mapping of the segment should replace any existing mapping in the range starting at shmaddr and continuing for the size of the segment. This flag is Linux-specific.
SHM_EXEC - allow the contents of the segment to be executed. Linux-specific.
Passing the value 0 means that all flags are unset. I wouldn't use NULL here, since NULL implies the parameter type is a pointer, which it is not.
See the shmat(2) man page.
The JVM Tool Interface has several call-stack related functions (e.g., GetStackTrace, GetFrameCount, or GetLocalInstance) which take a jthread as argument to determine the affected thread. All of them take a NULL argument to mean “the current thread.“
Now suppose I already have a jthread referring to the current thread. Which one is then faster?
Explicitly passing the current thread as jthread
Passing NULL
In LDD3's example, access_ok() is placed at the beginning of ioctl method of a kernel module to check whether a pointer passed from userspace is valid. It is correct when userspace application calls ioctl() system call, and passes it an address of a variable. In some cases, however, ioctl() system call is invoked with a value instead of a pointer as third argument and finally the second argument of access_ok() in kernel module.
I've tried to pass an integer as access_ok()'s second argument and it works fine. No error was reported. But I don't very sure that is this usage correct?
For example, if I invoke ioctl() in userspace with it's third argument to be '3'. Then, in ioctl() method of struct file_operations, access_ok() will receive 3 as it's second argument. Because the access_ok() expects a pointer, so it translates 3 to be a userspace pointer. Obversely, it's wrong...
Actually, access_ok's check is rough. Description of the function (in the source file) say:
Note that, depending on architecture, this function probably just
checks that the pointer is in the user space range - after calling
this function, memory access functions may still return -EFAULT.
E.g., according to source arch/x86/include/asm/uaccess.h, on x86 access_ok just checks that given address points to the lower area (because kernel besides in the upper area). So, it returns true for address equal to 3.
It is copy_from_user/copy_to_user who return a final verdict about user memory accessibility.
Userspace programs can give you any random value as a pointer, so access_ok() must be able to handle any random value.
So it is definitely OK to call access_ok() with a non-pointer value.
However, unless you are actually going to try to access that memory location, calling access_ok() is utterly pointless.
(For that matter, you should, if possible, avoid access_ok() and just check the actual userspace accesses (get_user() etc.) for errors.)
What is the difference between a thread ID and a thread handle? Why both are needed? Is there a difference between Windows and Linux?
Linux's pthread library does not, as far as I know, have a concept of a thread handle. pthread_create and other pthreads functions, return a thread ID.
Under Windows, the thread handle is different from the thread ID, in the same way that a file handle is different from a file name.
The thread handle is a token which allows you to do something with the thread (typically wait for it or kill it). Win32 has these tokens for lots of objects, and calls them HANDLE in general.
The token is essentially a pointer at the running (or stopped) thread and has a set of abilities associated with it, for example, you can have a handle which permits you to wait for, but not kill, a thread. In the same way, we can have a file handle which is read-only.
This level of indirection may or may not be useful, but it's the way Win32 does it, and it's broadly consistent with how it handles some other types of objects.
The ID is the unique numeric identifier of the thread running in the system. A thread handle, like any kernel object handle, can be seen as a special type of reference counted pointer to the kernel object.
So in kernel space there is an object of type THREAD with ID = 12345
And because you want to do something with the thread you have a pointer in your address space called a threadID with value 44.
Please note that different handles to the same kernel object have different values (two pointers to one object) and that kernel objects can have handles in more than one process.
Thread IDs are progressive (ie, one after another), which you can traverse.
Thread handles, like most handles in Windows, are actually pointers.
You might, for example, set thread property bits by using the thread handle - but not thread id.