• How to inline the main function of a thread?

    From Wuns Haerst@3:633/10 to All on Tue Jun 30 10:27:38 2026
    I measured the time it takes to create a thread on both Windows and
    Linux. On Windows, it takes around 120,000 clock cycles, whereas on
    Linux, it takes about a third of that.
    It occurred to me that one could simply inline the thread's main
    function. This would eliminate the need for the operating system
    call to create the thread. In this scenario, the compiler ? or its
    runtime ? would have to handle the scheduling.
    I estimate that this would reduce the thread creation overhead to
    just a few clock cycles, making thread pools unnecessary. I?m just
    not sure yet exactly how to go about implementing this. Perhaps
    someone here can help me with it.
    Please send any relevant suggestions via email only, as I intend
    to patent this idea once it is fully developed.

    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Chris M. Thomasson@3:633/10 to All on Tue Jun 30 01:42:37 2026
    On 6/30/2026 1:27 AM, Wuns Haerst wrote:
    I measured the time it takes to create a thread on both Windows and
    Linux. On Windows, it takes around 120,000 clock cycles, whereas on
    Linux, it takes about a third of that.
    It occurred to me that one could simply inline the thread's main
    function. This would eliminate the need for the operating system
    call to create the thread. In this scenario, the compiler ? or its
    runtime ? would have to handle the scheduling.
    I estimate that this would reduce the thread creation overhead to
    just a few clock cycles, making thread pools unnecessary. I?m just
    not sure yet exactly how to go about implementing this. Perhaps
    someone here can help me with it.
    Please send any relevant suggestions via email only, as I intend
    to patent this idea once it is fully developed.

    Well, we should never be creating threads all the time and joining them,
    ect. Just make a nice thread pool up front. Adding more threads to it
    should be fairly rare.


    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From David Brown@3:633/10 to All on Tue Jun 30 11:07:36 2026
    On 30/06/2026 10:27, Wuns Haerst wrote:
    I measured the time it takes to create a thread on both Windows and
    Linux. On Windows, it takes around 120,000 clock cycles, whereas on
    Linux, it takes about a third of that.
    It occurred to me that one could simply inline the thread's main
    function. This would eliminate the need for the operating system
    call to create the thread. In this scenario, the compiler ? or its
    runtime ? would have to handle the scheduling.
    I estimate that this would reduce the thread creation overhead to
    just a few clock cycles, making thread pools unnecessary. I?m just
    not sure yet exactly how to go about implementing this. Perhaps
    someone here can help me with it.
    Please send any relevant suggestions via email only, as I intend
    to patent this idea once it is fully developed.

    It sounds like you have little experience or understanding of
    multi-threading or multi-tasking, what "inlining" means, and what
    compilers and runtimes can do.

    For general threads or tasks on a general-purpose OS, what you are
    asking is not possible. People have got patents on impossible things
    before - plenty have been granted for perpetual motion machines - but
    it's a waste of time and effort. If you think you have had a brilliant
    idea to make multi-threading vastly more efficient, and no one else has thought of this before, you are delusional.

    It is entirely possible to have coroutines, lightweight threads, fibres, goroutines, protothreads, etc., that all run within the same OS thread
    but allow a certain amount of disconnection of execution. Generally
    speaking, the more flexibility and independence you have in the
    execution of these types of thread, the greater the overhead in creating
    them. If they are actually going to run simultaneously on a multi-core system, you will be using OS threads somewhere.

    The lowest overhead existing solution, to my knowledge, is
    "protothreads". C++ has standardised support for coroutines, though it
    is a bit clunky as a late addition to the language. Go has goroutines
    that are fundamental to the language, and thus better integrated.


    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From boltar@3:633/10 to All on Tue Jun 30 10:41:55 2026
    On Tue, 30 Jun 2026 10:27:38 +0200
    Wuns Haerst <Wuns.Haerst@wurstfabrik.at> gabbled:
    I measured the time it takes to create a thread on both Windows and
    Linux. On Windows, it takes around 120,000 clock cycles, whereas on
    Linux, it takes about a third of that.
    It occurred to me that one could simply inline the thread's main
    function. This would eliminate the need for the operating system

    Wtf are you babbling about? Its jumping into kernel mode and the kernel adding another thread to its scheduler that takes most of the time.

    call to create the thread. In this scenario, the compiler ? or its
    runtime ? would have to handle the scheduling.
    I estimate that this would reduce the thread creation overhead to
    just a few clock cycles, making thread pools unnecessary. I?m just
    not sure yet exactly how to go about implementing this. Perhaps
    someone here can help me with it.
    Please send any relevant suggestions via email only, as I intend
    to patent this idea once it is fully developed.

    Clown. You can't patent software methods in most of the world. Also asking people for ideas then saying you'll patent them will get you zero responses othe than derision.


    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From boltar@3:633/10 to All on Tue Jun 30 10:44:30 2026
    On Tue, 30 Jun 2026 01:42:37 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 6/30/2026 1:27 AM, Wuns Haerst wrote:
    I measured the time it takes to create a thread on both Windows and
    Linux. On Windows, it takes around 120,000 clock cycles, whereas on
    Linux, it takes about a third of that.
    It occurred to me that one could simply inline the thread's main
    function. This would eliminate the need for the operating system
    call to create the thread. In this scenario, the compiler ? or its
    runtime ? would have to handle the scheduling.
    I estimate that this would reduce the thread creation overhead to
    just a few clock cycles, making thread pools unnecessary. I?m just
    not sure yet exactly how to go about implementing this. Perhaps
    someone here can help me with it.
    Please send any relevant suggestions via email only, as I intend
    to patent this idea once it is fully developed.

    Well, we should never be creating threads all the time and joining them, >ect. Just make a nice thread pool up front. Adding more threads to it
    should be fairly rare.

    "Just make a threadpool" is a non trivial coding task and completely unnecessary for programs that only create threads ad hoc now and then. If you're writing a high throughput server then sure, otherwise no.


    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From boltar@3:633/10 to All on Tue Jun 30 10:46:22 2026
    On Tue, 30 Jun 2026 11:07:36 +0200
    David Brown <david.brown@hesbynett.no> gabbled:
    The lowest overhead existing solution, to my knowledge, is
    "protothreads". C++ has standardised support for coroutines, though it
    is a bit clunky as a late addition to the language. Go has goroutines

    They're a badly specced solution looking for a problem whose logic can already be solved with function static autos and/or thread local vars.


    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Scott Lurndal@3:633/10 to All on Tue Jun 30 14:14:47 2026
    Wuns Haerst <Wuns.Haerst@wurstfabrik.at> writes:
    I measured the time it takes to create a thread on both Windows and
    Linux. On Windows, it takes around 120,000 clock cycles, whereas on
    Linux, it takes about a third of that.
    It occurred to me that one could simply inline the thread's main
    function. This would eliminate the need for the operating system
    call to create the thread. In this scenario, the compiler ? or its
    runtime ? would have to handle the scheduling.
    I estimate that this would reduce the thread creation overhead to
    just a few clock cycles, making thread pools unnecessary. I?m just
    not sure yet exactly how to go about implementing this. Perhaps
    someone here can help me with it.
    Please send any relevant suggestions via email only, as I intend
    to patent this idea once it is fully developed.

    Don't bother. It's been done, more than once. See, for example,
    Unixware 2.0. It turns out that userspace thread scheduling
    does not perform as well as kernel-based thread scheduling.


    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Bonita Montero@3:633/10 to All on Tue Jun 30 16:30:05 2026
    Am 30.06.2026 um 16:14 schrieb Scott Lurndal:

    Don't bother. It's been done, more than once. See, for example,
    Unixware 2.0. It turns out that userspace thread scheduling
    does not perform as well as kernel-based thread scheduling.

    Fiber-like context-switchs are *much* faster than through the kernel.
    The problem with that is you don't have any context switchs among
    your "threads" when you run kernel-code.
    Oracle does user-level scheduling and solves the kernel-issue by
    never calling any blocking kernel-calls.

    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Scott Lurndal@3:633/10 to All on Tue Jun 30 15:25:28 2026
    Bonita Montero <Bonita.Montero@gmail.com> writes:
    Am 30.06.2026 um 16:14 schrieb Scott Lurndal:

    Don't bother. It's been done, more than once. See, for example,
    Unixware 2.0. It turns out that userspace thread scheduling
    does not perform as well as kernel-based thread scheduling.

    Fiber-like context-switchs are *much* faster than through the kernel.
    The problem with that is you don't have any context switchs among
    your "threads" when you run kernel-code.
    Oracle does user-level scheduling and solves the kernel-issue by
    never calling any blocking kernel-calls.

    How do you know how the oracle RDBMS works internally?

    (I did spend some time working with the RDBMS sources in the 90s).

    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From boltar@3:633/10 to All on Tue Jun 30 15:39:25 2026
    On Tue, 30 Jun 2026 14:14:47 GMT
    scott@slp53.sl.home (Scott Lurndal) gabbled:
    Wuns Haerst <Wuns.Haerst@wurstfabrik.at> writes:
    I measured the time it takes to create a thread on both Windows and
    Linux. On Windows, it takes around 120,000 clock cycles, whereas on
    Linux, it takes about a third of that.
    It occurred to me that one could simply inline the thread's main
    function. This would eliminate the need for the operating system
    call to create the thread. In this scenario, the compiler ? or its
    runtime ? would have to handle the scheduling.
    I estimate that this would reduce the thread creation overhead to
    just a few clock cycles, making thread pools unnecessary. I?m just
    not sure yet exactly how to go about implementing this. Perhaps
    someone here can help me with it.
    Please send any relevant suggestions via email only, as I intend
    to patent this idea once it is fully developed.

    Don't bother. It's been done, more than once. See, for example,
    Unixware 2.0. It turns out that userspace thread scheduling
    does not perform as well as kernel-based thread scheduling.

    Java of course being a prime example with its green threads.


    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Wuns Haerst@3:633/10 to All on Tue Jun 30 18:00:23 2026
    Am 30.06.2026 um 17:39 schrieb boltar@caprica.universe:

    On Tue, 30 Jun 2026 14:14:47 GMT

    Don't bother. It's been done, more than once. See, for example,
    Unixware 2.0. It turns out that userspace thread scheduling
    does not perform as well as kernel-based thread scheduling.

    Java of course being a prime example with its green threads.

    According to Wikipedia Java had green threads between 1997 and 2000.

    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Scott Lurndal@3:633/10 to All on Tue Jun 30 17:05:50 2026
    Wuns Haerst <Wuns.Haerst@wurstfabrik.at> writes:
    Am 30.06.2026 um 17:39 schrieb boltar@caprica.universe:

    On Tue, 30 Jun 2026 14:14:47 GMT

    Don't bother. It's been done, more than once. See, for example,
    Unixware 2.0. It turns out that userspace thread scheduling
    does not perform as well as kernel-based thread scheduling.

    Java of course being a prime example with its green threads.

    According to Wikipedia Java had green threads between 1997 and 2000.

    Only on linux. Java on SunOS/Solaris/Unixware used Unix[*] threads.

    [*] Unix threads were multi-level M:N threads supporting a user
    space thread manager multiplexing M user threads on N underlying
    light-weight-processes (LWPs - AKA kernel threads). The app
    could configure the ratio as 1:1, and I suspect, but cannot
    confirm, that Java used 1:1 threads on the Unix(R) systems.

    When 1003.4 was being developed, such thread multiplexing
    was proposed, but ultimately wasn't included in the
    POSIX thread specification.

    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Michael S@3:633/10 to All on Tue Jun 30 23:29:59 2026
    On Tue, 30 Jun 2026 10:27:38 +0200
    Wuns Haerst <Wuns.Haerst@wurstfabrik.at> wrote:

    I measured the time it takes to create a thread on both Windows and
    Linux. On Windows, it takes around 120,000 clock cycles, whereas on
    Linux, it takes about a third of that.
    It occurred to me that one could simply inline the thread's main
    function. This would eliminate the need for the operating system
    call to create the thread. In this scenario, the compiler ? or its
    runtime ? would have to handle the scheduling.
    I estimate that this would reduce the thread creation overhead to
    just a few clock cycles, making thread pools unnecessary. I?m just
    not sure yet exactly how to go about implementing this. Perhaps
    someone here can help me with it.
    Please send any relevant suggestions via email only, as I intend
    to patent this idea once it is fully developed.

    In majority of situations you don't need to create threads on Window.
    Use one of the several available Windows thread pool APIs.
    For example, QueueUserWorkItem() - somewhat outdated and not
    feature-rich, but very easy to use.

    Of course, in C++ group it is of topic, because it does not map itself
    well into C++ std::thread model. But that should not stop you if it is
    a right answer to youur needs.


    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From boltar@3:633/10 to All on Wed Jul 1 08:22:02 2026
    On Tue, 30 Jun 2026 17:05:50 GMT
    scott@slp53.sl.home (Scott Lurndal) gabbled:
    Wuns Haerst <Wuns.Haerst@wurstfabrik.at> writes:
    Am 30.06.2026 um 17:39 schrieb boltar@caprica.universe:

    On Tue, 30 Jun 2026 14:14:47 GMT

    Don't bother. It's been done, more than once. See, for example,
    Unixware 2.0. It turns out that userspace thread scheduling
    does not perform as well as kernel-based thread scheduling.

    Java of course being a prime example with its green threads.

    According to Wikipedia Java had green threads between 1997 and 2000.

    Only on linux. Java on SunOS/Solaris/Unixware used Unix[*] threads.

    IIRC threads on linux up until kernel 3 were actually seperate processes with
    a behind the scenes userspace hack to share process data. No idea why threads weren't built into the kernel from the start, perhaps too complicated or Linus didn't see the point of them.


    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Chris M. Thomasson@3:633/10 to All on Wed Jul 1 12:23:45 2026
    On 6/30/2026 3:44 AM, boltar@caprica.universe wrote:
    On Tue, 30 Jun 2026 01:42:37 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 6/30/2026 1:27 AM, Wuns Haerst wrote:
    I measured the time it takes to create a thread on both Windows and
    Linux. On Windows, it takes around 120,000 clock cycles, whereas on
    Linux, it takes about a third of that.
    It occurred to me that one could simply inline the thread's main
    function. This would eliminate the need for the operating system
    call to create the thread. In this scenario, the compiler ? or its
    runtime ? would have to handle the scheduling.
    I estimate that this would reduce the thread creation overhead to
    just a few clock cycles, making thread pools unnecessary. I?m just
    not sure yet exactly how to go about implementing this. Perhaps
    someone here can help me with it.
    Please send any relevant suggestions via email only, as I intend
    to patent this idea once it is fully developed.

    Well, we should never be creating threads all the time and joining
    them, ect. Just make a nice thread pool up front. Adding more threads
    to it should be fairly rare.

    "Just make a threadpool" is a non trivial coding task and completely unnecessary for programs that only create threads ad hoc now and then. If you're writing a high throughput server then sure, otherwise no.


    Thread pools are not all that hard. Since you are using threads anyway,
    how are you handling the sync in your program logic to them? What do
    they do?

    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Chris M. Thomasson@3:633/10 to All on Wed Jul 1 12:25:44 2026
    On 6/30/2026 3:46 AM, boltar@caprica.universe wrote:
    On Tue, 30 Jun 2026 11:07:36 +0200
    David Brown <david.brown@hesbynett.no> gabbled:
    The lowest overhead existing solution, to my knowledge, is
    "protothreads".ÿ C++ has standardised support for coroutines, though
    it is a bit clunky as a late addition to the language.ÿ Go has goroutines

    They're a badly specced solution looking for a problem whose logic can already
    be solved with function static autos and/or thread local vars.


    How much experience do you have with per_thread data?

    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Chris M. Thomasson@3:633/10 to All on Wed Jul 1 12:30:28 2026
    On 6/30/2026 8:25 AM, Scott Lurndal wrote:
    Bonita Montero <Bonita.Montero@gmail.com> writes:
    Am 30.06.2026 um 16:14 schrieb Scott Lurndal:

    Don't bother. It's been done, more than once. See, for example,
    Unixware 2.0. It turns out that userspace thread scheduling
    does not perform as well as kernel-based thread scheduling.

    Fiber-like context-switchs are *much* faster than through the kernel.
    The problem with that is you don't have any context switchs among
    your "threads" when you run kernel-code.
    Oracle does user-level scheduling and solves the kernel-issue by
    never calling any blocking kernel-calls.

    How do you know how the oracle RDBMS works internally?

    (I did spend some time working with the RDBMS sources in the 90s).

    I don't think he knows. Its funny how he mentions never calling a
    blocking kernel call in a thread. GetQueuedCompletionStatusEx over in
    the windozer, can be blocking kernel call, aka using a non-zero timeout.

    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From boltar@3:633/10 to All on Thu Jul 2 08:13:13 2026
    On Wed, 1 Jul 2026 12:23:45 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 6/30/2026 3:44 AM, boltar@caprica.universe wrote:
    On Tue, 30 Jun 2026 01:42:37 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 6/30/2026 1:27 AM, Wuns Haerst wrote:
    I measured the time it takes to create a thread on both Windows and
    Linux. On Windows, it takes around 120,000 clock cycles, whereas on
    Linux, it takes about a third of that.
    It occurred to me that one could simply inline the thread's main
    function. This would eliminate the need for the operating system
    call to create the thread. In this scenario, the compiler ? or its
    runtime ? would have to handle the scheduling.
    I estimate that this would reduce the thread creation overhead to
    just a few clock cycles, making thread pools unnecessary. I?m just
    not sure yet exactly how to go about implementing this. Perhaps
    someone here can help me with it.
    Please send any relevant suggestions via email only, as I intend
    to patent this idea once it is fully developed.

    Well, we should never be creating threads all the time and joining
    them, ect. Just make a nice thread pool up front. Adding more threads
    to it should be fairly rare.

    "Just make a threadpool" is a non trivial coding task and completely
    unnecessary for programs that only create threads ad hoc now and then. If
    you're writing a high throughput server then sure, otherwise no.


    Thread pools are not all that hard. Since you are using threads anyway,

    They're hard enough to make it a lot of pointless work if its not
    necessary. As I said, if you're creating threads every few milliseconds then use a thread pool. If you're just creating a thread every few seconds or longer then a pool is a complete waste of time.

    how are you handling the sync in your program logic to them? What do
    they do?

    Is that supposed to be some kind of trick question?


    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From boltar@3:633/10 to All on Thu Jul 2 08:13:29 2026
    On Wed, 1 Jul 2026 12:25:44 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 6/30/2026 3:46 AM, boltar@caprica.universe wrote:
    On Tue, 30 Jun 2026 11:07:36 +0200
    David Brown <david.brown@hesbynett.no> gabbled:
    The lowest overhead existing solution, to my knowledge, is
    "protothreads".ÿ C++ has standardised support for coroutines, though
    it is a bit clunky as a late addition to the language.ÿ Go has goroutines >>
    They're a badly specced solution looking for a problem whose logic can
    already
    be solved with function static autos and/or thread local vars.


    How much experience do you have with per_thread data?

    Plenty. Next...


    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Chris M. Thomasson@3:633/10 to All on Thu Jul 2 11:41:48 2026
    On 7/2/2026 1:13 AM, boltar@caprica.universe wrote:
    On Wed, 1 Jul 2026 12:23:45 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 6/30/2026 3:44 AM, boltar@caprica.universe wrote:
    On Tue, 30 Jun 2026 01:42:37 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 6/30/2026 1:27 AM, Wuns Haerst wrote:
    I measured the time it takes to create a thread on both Windows and
    Linux. On Windows, it takes around 120,000 clock cycles, whereas on
    Linux, it takes about a third of that.
    It occurred to me that one could simply inline the thread's main
    function. This would eliminate the need for the operating system
    call to create the thread. In this scenario, the compiler ? or its
    runtime ? would have to handle the scheduling.
    I estimate that this would reduce the thread creation overhead to
    just a few clock cycles, making thread pools unnecessary. I?m just
    not sure yet exactly how to go about implementing this. Perhaps
    someone here can help me with it.
    Please send any relevant suggestions via email only, as I intend
    to patent this idea once it is fully developed.

    Well, we should never be creating threads all the time and joining
    them, ect. Just make a nice thread pool up front. Adding more
    threads to it should be fairly rare.

    "Just make a threadpool" is a non trivial coding task and completely
    unnecessary for programs that only create threads ad hoc now and
    then. If
    you're writing a high throughput server then sure, otherwise no.


    Thread pools are not all that hard. Since you are using threads anyway,

    They're hard enough to make it a lot of pointless work if its not
    necessary. As I said, if you're creating threads every few milliseconds
    then
    use a thread pool. If you're just creating a thread every few seconds or longer then a pool is a complete waste of time.

    Thread per connection model? If that works for your work load, so be it.
    Just don't be alarmed if you get 10000 threads all of sudden. Or, say a connection comes in every second for say a half an hour. 1800
    connections? Also you need to think about a connection that sends a
    little data then just sits there doing nothing for say 20 minutes.


    how are you handling the sync in your program logic to them? What do
    they do?

    Is that supposed to be some kind of trick question?

    No. It means how to you say, join them, or are you detaching them? How
    can you gain data from them? You need to know all about this if you are
    going to use threads at all. Well, imvho that is...

    Do you have a "reaper" thread that can conduct "maintenance"? Zombie
    states? Are you do graceful shutdowns?

    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From boltar@3:633/10 to All on Fri Jul 3 08:59:43 2026
    On Thu, 2 Jul 2026 11:41:48 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/2/2026 1:13 AM, boltar@caprica.universe wrote:
    They're hard enough to make it a lot of pointless work if its not
    necessary. As I said, if you're creating threads every few milliseconds
    then
    use a thread pool. If you're just creating a thread every few seconds or
    longer then a pool is a complete waste of time.

    Thread per connection model? If that works for your work load, so be it. >Just don't be alarmed if you get 10000 threads all of sudden. Or, say a >connection comes in every second for say a half an hour. 1800
    connections? Also you need to think about a connection that sends a
    little data then just sits there doing nothing for say 20 minutes.

    You do realise setting up and pulling down a TCP connection takes far more
    CPU resources than simply adding a new program counter into the scheduler
    list, right? If we were talking about creating a new process via fork() then your argument might have some merit, but threads? No.

    how are you handling the sync in your program logic to them? What do
    they do?

    Is that supposed to be some kind of trick question?

    No. It means how to you say, join them, or are you detaching them? How
    can you gain data from them? You need to know all about this if you are >going to use threads at all. Well, imvho that is...

    I would imagine most threads in a server process run detached. Joining makes little sense unless you specifically need to wait for the thread to complete its task in which case there might be an argument for doing the task sequentially anyway.

    Do you have a "reaper" thread that can conduct "maintenance"? Zombie
    states? Are you do graceful shutdowns?

    I'd hate to see your code, must be an overcomplicated mess.


    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Scott Lurndal@3:633/10 to All on Fri Jul 3 14:41:29 2026
    boltar@caprica.universe writes:
    On Thu, 2 Jul 2026 11:41:48 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:

    Thread per connection model? If that works for your work load, so be it. >>Just don't be alarmed if you get 10000 threads all of sudden. Or, say a >>connection comes in every second for say a half an hour. 1800
    connections? Also you need to think about a connection that sends a
    little data then just sits there doing nothing for say 20 minutes.

    You do realise setting up and pulling down a TCP connection takes far more >CPU resources than simply adding a new program counter into the scheduler >list, right?

    You're clearly not an expert on operating systems. There's far
    more involved than "simply adding a new program counter to the scheduler list" during thread creation.

    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From boltar@3:633/10 to All on Fri Jul 3 15:59:54 2026
    On Fri, 03 Jul 2026 14:41:29 GMT
    scott@slp53.sl.home (Scott Lurndal) gabbled:
    boltar@caprica.universe writes:
    On Thu, 2 Jul 2026 11:41:48 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:

    Thread per connection model? If that works for your work load, so be it. >>>Just don't be alarmed if you get 10000 threads all of sudden. Or, say a >>>connection comes in every second for say a half an hour. 1800 >>>connections? Also you need to think about a connection that sends a >>>little data then just sits there doing nothing for say 20 minutes.

    You do realise setting up and pulling down a TCP connection takes far more >>CPU resources than simply adding a new program counter into the scheduler >>list, right?

    You're clearly not an expert on operating systems. There's far
    more involved than "simply adding a new program counter to the scheduler list" >during thread creation.

    Actually there isn't that much more but if you think otherwise do fill us in
    on the details.


    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Ross Finlayson@3:633/10 to All on Fri Jul 3 10:45:05 2026
    On 07/02/2026 11:41 AM, Chris M. Thomasson wrote:
    On 7/2/2026 1:13 AM, boltar@caprica.universe wrote:
    On Wed, 1 Jul 2026 12:23:45 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 6/30/2026 3:44 AM, boltar@caprica.universe wrote:
    On Tue, 30 Jun 2026 01:42:37 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 6/30/2026 1:27 AM, Wuns Haerst wrote:
    I measured the time it takes to create a thread on both Windows and >>>>>> Linux. On Windows, it takes around 120,000 clock cycles, whereas on >>>>>> Linux, it takes about a third of that.
    It occurred to me that one could simply inline the thread's main
    function. This would eliminate the need for the operating system
    call to create the thread. In this scenario, the compiler ? or its >>>>>> runtime ? would have to handle the scheduling.
    I estimate that this would reduce the thread creation overhead to
    just a few clock cycles, making thread pools unnecessary. I?m just >>>>>> not sure yet exactly how to go about implementing this. Perhaps
    someone here can help me with it.
    Please send any relevant suggestions via email only, as I intend
    to patent this idea once it is fully developed.

    Well, we should never be creating threads all the time and joining
    them, ect. Just make a nice thread pool up front. Adding more
    threads to it should be fairly rare.

    "Just make a threadpool" is a non trivial coding task and completely
    unnecessary for programs that only create threads ad hoc now and
    then. If
    you're writing a high throughput server then sure, otherwise no.


    Thread pools are not all that hard. Since you are using threads anyway,

    They're hard enough to make it a lot of pointless work if its not
    necessary. As I said, if you're creating threads every few
    milliseconds then
    use a thread pool. If you're just creating a thread every few seconds
    or longer then a pool is a complete waste of time.

    Thread per connection model? If that works for your work load, so be it.
    Just don't be alarmed if you get 10000 threads all of sudden. Or, say a connection comes in every second for say a half an hour. 1800
    connections? Also you need to think about a connection that sends a
    little data then just sits there doing nothing for say 20 minutes.


    how are you handling the sync in your program logic to them? What do
    they do?

    Is that supposed to be some kind of trick question?

    No. It means how to you say, join them, or are you detaching them? How
    can you gain data from them? You need to know all about this if you are
    going to use threads at all. Well, imvho that is...

    Do you have a "reaper" thread that can conduct "maintenance"? Zombie
    states? Are you do graceful shutdowns?

    "Sweeper" usually it's called, here, for the case of timeouts.


    Have you heard of re-routines? It's a model of co-operative
    multi-threading with async everywhere yet written in the language as
    procedural flow of control with exceptions, thusly "async" nowhere.

    Have you heard of re-routines? ....



    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Chris M. Thomasson@3:633/10 to All on Fri Jul 3 12:36:03 2026
    On 7/3/2026 10:45 AM, Ross Finlayson wrote:
    On 07/02/2026 11:41 AM, Chris M. Thomasson wrote:
    On 7/2/2026 1:13 AM, boltar@caprica.universe wrote:
    On Wed, 1 Jul 2026 12:23:45 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 6/30/2026 3:44 AM, boltar@caprica.universe wrote:
    On Tue, 30 Jun 2026 01:42:37 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 6/30/2026 1:27 AM, Wuns Haerst wrote:
    I measured the time it takes to create a thread on both Windows and >>>>>>> Linux. On Windows, it takes around 120,000 clock cycles, whereas on >>>>>>> Linux, it takes about a third of that.
    It occurred to me that one could simply inline the thread's main >>>>>>> function. This would eliminate the need for the operating system >>>>>>> call to create the thread. In this scenario, the compiler ? or its >>>>>>> runtime ? would have to handle the scheduling.
    I estimate that this would reduce the thread creation overhead to >>>>>>> just a few clock cycles, making thread pools unnecessary. I?m just >>>>>>> not sure yet exactly how to go about implementing this. Perhaps
    someone here can help me with it.
    Please send any relevant suggestions via email only, as I intend >>>>>>> to patent this idea once it is fully developed.

    Well, we should never be creating threads all the time and joining >>>>>> them, ect. Just make a nice thread pool up front. Adding more
    threads to it should be fairly rare.

    "Just make a threadpool" is a non trivial coding task and completely >>>>> unnecessary for programs that only create threads ad hoc now and
    then. If
    you're writing a high throughput server then sure, otherwise no.


    Thread pools are not all that hard. Since you are using threads anyway, >>>
    They're hard enough to make it a lot of pointless work if its not
    necessary. As I said, if you're creating threads every few
    milliseconds then
    use a thread pool. If you're just creating a thread every few seconds
    or longer then a pool is a complete waste of time.

    Thread per connection model? If that works for your work load, so be it.
    Just don't be alarmed if you get 10000 threads all of sudden. Or, say a
    connection comes in every second for say a half an hour. 1800
    connections? Also you need to think about a connection that sends a
    little data then just sits there doing nothing for say 20 minutes.


    how are you handling the sync in your program logic to them? What do
    they do?

    Is that supposed to be some kind of trick question?

    No. It means how to you say, join them, or are you detaching them? How
    can you gain data from them? You need to know all about this if you are
    going to use threads at all. Well, imvho that is...

    Do you have a "reaper" thread that can conduct "maintenance"? Zombie
    states? Are you do graceful shutdowns?

    "Sweeper" usually it's called, here, for the case of timeouts.

    Timeouts, general maintenance, etc. Fwiw, it can be a single function
    that can be run on any thread. Say to gain entry:


    if (try_lock())
    {
    // reaper logic

    unlock();
    }


    that way any thread can act like a reaper, but its "best" to keep that
    in a dedicated thread. Also, it ensures that only one reaper is alive at
    any one time and its non-blocking via try_lock. Its just an easy way to
    do it.

    Reaper logic never blocks.


    Have you heard of re-routines? It's a model of co-operative
    multi-threading with async everywhere yet written in the language as procedural flow of control with exceptions, thusly "async" nowhere.

    Have you heard of re-routines? ....


    Building on top of coroutines, with a stack? Like Fibers? I have used continuations before. But, re-routines? Humm... Not ringing a bell.

    Fwiw, here is a fun paper I read many moons ago, iirc back in 2002:

    https://www.microsoft.com/en-us/research/publication/using-cohort-scheduling-to-enhance-server-performance/?msockid=156c5513e5e96cdb283d4228e46a6db8

    https://www.microsoft.com/en-us/research/wp-content/uploads/2016/02/tr-2001-39.pdf

    This was way back when I was working with winnt 4.0.

    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Chris M. Thomasson@3:633/10 to All on Fri Jul 3 12:44:07 2026
    On 7/3/2026 1:59 AM, boltar@caprica.universe wrote:
    On Thu, 2 Jul 2026 11:41:48 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/2/2026 1:13 AM, boltar@caprica.universe wrote:
    They're hard enough to make it a lot of pointless work if its not
    necessary. As I said, if you're creating threads every few
    milliseconds then
    use a thread pool. If you're just creating a thread every few seconds
    or longer then a pool is a complete waste of time.

    Thread per connection model? If that works for your work load, so be
    it. Just don't be alarmed if you get 10000 threads all of sudden. Or,
    say a connection comes in every second for say a half an hour. 1800
    connections? Also you need to think about a connection that sends a
    little data then just sits there doing nothing for say 20 minutes.

    You do realise setting up and pulling down a TCP connection takes far more CPU resources than simply adding a new program counter into the scheduler list, right? If we were talking about creating a new process via fork()
    then
    your argument might have some merit, but threads? No.

    how are you handling the sync in your program logic to them? What do
    they do?

    Is that supposed to be some kind of trick question?

    No. It means how to you say, join them, or are you detaching them? How
    can you gain data from them? You need to know all about this if you
    are going to use threads at all. Well, imvho that is...

    I would imagine most threads in a server process run detached. Joining
    makes
    little sense unless you specifically need to wait for the thread to
    complete
    its task in which case there might be an argument for doing the task sequentially anyway.

    Do you have a "reaper" thread that can conduct "maintenance"? Zombie
    states? Are you do graceful shutdowns?

    I'd hate to see your code, must be an overcomplicated mess.


    Set your coffee down! Here is my raw test for my mind trying to sketch
    out an IOCP server setup from my memory... It should compile for you, I
    will show my ralloc code in follow up. I had a little trouble
    remembering what the AcceptEx format for buffers is, IPv4 here. There
    should be a sockaddrs for ipv6. Sigh, but I got this for now. Almost
    ready for a proper thread pool! :^D

    ct_main.cpp
    ________



    #include "ct_ralloc.hpp"

    #include <cstdio>
    #include <cstdlib>
    #include <cassert>

    #include <iostream>
    #include <thread>
    #include <atomic>
    #include <mutex>
    #include <vector>


    #define WIN32_LEAN_AND_MEAN
    #include <winsock2.h>
    #include <ws2tcpip.h>
    #include <iphlpapi.h>
    #include <mswsock.h>
    #include <windows.h>






    namespace ct
    {
    namespace tools
    {
    template<typename T>
    struct ctor_dtor
    {
    T* m_ptr;

    ctor_dtor(
    T* ptr
    ): m_ptr(ptr) {
    m_ptr->ctor();
    }

    ~ctor_dtor()
    {
    m_ptr->dtor();
    }
    };

    template<typename T>
    struct dtor
    {
    T* m_ptr;

    dtor(
    T* ptr
    ) : m_ptr(ptr) {

    }

    ~dtor()
    {
    m_ptr->dtor();
    }
    };
    }


    namespace proxy_0_0_0_0
    {
    struct atomic_region
    {
    unsigned char* m_raw_buffer = nullptr;
    std::size_t m_usable = 0;
    std::atomic<std::size_t> m_head = { 0 };

    // move it out into an init...
    void
    init(
    unsigned char* const raw_buffer,
    std::size_t usable
    ) {
    m_raw_buffer = raw_buffer;
    m_usable = usable;
    m_head.store(0, std::memory_order_relaxed);
    }



    unsigned char*
    alloc(
    std::size_t size
    ) {
    /*
    std::size_t old = m_head.fetch_add(size, std::memory_order_relaxed);

    if (old + size > m_usable)
    {
    m_head.exchange(m_usable, std::memory_order_relaxed);

    return nullptr;
    }
    */

    // using a CAS loop here. Sigh. Shit happens! ;^)
    std::size_t old = m_head.load(std::memory_order_relaxed);

    do
    {
    if (old + size > m_usable) return nullptr;
    } while (! m_head.compare_exchange_weak(old, old +
    size, std::memory_order_relaxed));

    return m_raw_buffer + old;
    }
    };



    namespace win
    {
    bool
    close_handle(
    HANDLE handle
    ) {
    BOOL status = CloseHandle(handle);

    if (! status)
    {
    assert(status && "close_handle failed... God damn
    it!");
    // throw; Grrrr! SHIT is REALLY BAD!
    // formatmessage, display? ;^)
    return false;
    }

    return true;
    }


    struct alignas(MEMORY_ALLOCATION_ALIGNMENT) slist_node {
    SLIST_ENTRY entry;
    };

    // Non-templated raw list (if n ever want it)
    struct slist_raw {
    SLIST_HEADER head;

    void init() noexcept {
    InitializeSListHead(&head);
    }

    void push(slist_node* n) noexcept {
    InterlockedPushEntrySList(&head, &n->entry);
    }

    slist_node* pop() noexcept {
    SLIST_ENTRY* e = InterlockedPopEntrySList(&head);
    return e ? CONTAINING_RECORD(e, slist_node, entry)
    : nullptr;
    }

    void flush() noexcept {
    InterlockedFlushSList(&head);
    }
    };




    struct wsa_extensions
    {
    LPFN_ACCEPTEX m_acceptex = nullptr;
    LPFN_CONNECTEX m_connectex = nullptr;
    LPFN_DISCONNECTEX m_disconnectex = nullptr;
    LPFN_GETACCEPTEXSOCKADDRS m_getacceptexsockaddrs = nullptr;

    bool
    load(
    SOCKET socket
    ) {
    if (!load_fn(socket, WSAID_ACCEPTEX, &m_acceptex))
    return false;
    if (!load_fn(socket, WSAID_CONNECTEX,
    &m_connectex)) return false;
    if (!load_fn(socket, WSAID_DISCONNECTEX, &m_disconnectex)) return false;
    if (!load_fn(socket, WSAID_GETACCEPTEXSOCKADDRS,
    &m_getacceptexsockaddrs))
    return false;

    std::cout <<
    "(" << this << ")->"
    "ct::proxy_0_0_0_0::win::"
    "wsa_extensions::load()\n"
    " m_acceptex = " << m_acceptex << "\n"
    " m_connectex = " << m_connectex <<
    "\n"
    " m_disconnectex = " << m_disconnectex
    << "\n"
    " m_getacceptexsockaddrs = " << m_getacceptexsockaddrs << "\n";

    return true;
    }

    private:

    template<typename T>
    bool
    load_fn(
    SOCKET socket,
    GUID guid,
    T* fn_out
    ) {
    DWORD bytes = 0;

    int status = WSAIoctl(
    socket,
    SIO_GET_EXTENSION_FUNCTION_POINTER,
    &guid, sizeof(guid),
    fn_out, sizeof(*fn_out),
    &bytes,
    nullptr,
    nullptr
    );

    if (status == SOCKET_ERROR)
    {
    std::cout << "WSAIoctl() failed: " << WSAGetLastError() << "\n";
    return false;
    }

    return true;
    }
    };


    struct winsock
    {
    WSADATA m_wsa_data = { };
    wsa_extensions m_wsaex = { };

    // extend for version...
    winsock()
    {
    int status = WSAStartup(MAKEWORD(2, 2), &m_wsa_data);

    if (status) {
    std::cout << "WSAStartup() failed...\n";
    throw std::runtime_error("WSAStartup failed");
    }

    std::cout << "WSAStartup()\n";
    }

    ~winsock()
    {
    if (WSACleanup() == SOCKET_ERROR)
    {
    std::cout << "WSACleanup() failed...\n";
    return;
    }

    std::cout << "WSACleanup()\n";
    }
    };


    struct addr_info
    {
    addrinfo* m_result = nullptr;
    addrinfo* m_ptr = nullptr;
    addrinfo m_hints = { };

    // need to extend add params
    addr_info()
    {
    m_hints.ai_family = AF_INET;
    m_hints.ai_socktype = SOCK_STREAM;
    m_hints.ai_protocol = IPPROTO_TCP;
    m_hints.ai_flags = AI_PASSIVE;

    // resolve?
    int status = getaddrinfo(nullptr, "8080", &m_hints, &m_result);
    if (status)
    {
    std::cout << "getaddrinfo() failed...\n";
    throw std::runtime_error("getaddrinfo failed");
    }

    std::cout << "addr_info::addr_info()\n";
    }

    ~addr_info()
    {
    freeaddrinfo(m_result);
    std::cout << "addr_info::~addr_info()\n";
    }
    };


    struct iocp
    {
    HANDLE m_iocp = nullptr;

    iocp(
    HANDLE handle = INVALID_HANDLE_VALUE,
    HANDLE existing = nullptr,
    ULONG_PTR key = 0,
    DWORD thread_n = 0
    ) {
    m_iocp = CreateIoCompletionPort(handle, existing,
    key, thread_n);

    if (! m_iocp)
    {
    DWORD last_error = GetLastError();

    std::cout <<
    "(" << this << ")->"
    "ct::proxy_0_0_0_0::win::"
    "iocp::iocp()::last_error = " <<
    last_error;

    throw
    std::runtime_error("CreateIoCompletionPort failed");
    }

    std::cout <<
    "(" << this << ")->"
    "ct::proxy_0_0_0_0::win::"
    "iocp::iocp()::ctor()\n";
    }

    ~iocp()
    {
    if (! m_iocp)
    {
    assert(false && "m_iocp unexpectedly null in destructor, fuck it all!");
    // fuc% me! GRRRR!
    return;
    }

    if (! close_handle(m_iocp))
    {
    // really bad!
    return;
    }

    std::cout <<
    "(" << this << ")->"
    "ct::proxy_0_0_0_0::win::"
    "iocp::iocp()::dtor()\n";
    }

    // no APC shit for now...
    DWORD
    gqcsex(
    LPOVERLAPPED_ENTRY pol_inout,
    ULONG pol_in_n,
    PULONG pol_out_n,
    DWORD timeout = INFINITE
    ) {
    if (! GetQueuedCompletionStatusEx(
    m_iocp,
    pol_inout,
    pol_in_n,
    pol_out_n,
    timeout,
    FALSE
    )) {

    // humm, iirc these can be tricky...

    DWORD last_error = GetLastError();

    std::cout <<
    "(" << this << ")->"
    "ct::proxy_0_0_0_0::win::"
    "iocp::gqcsex()::last_error = " <<
    last_error;

    // humm remember FormatMessage

    return last_error;
    }

    return 0;
    }

    HANDLE
    bind(
    HANDLE handle,
    ULONG_PTR key
    ) {
    HANDLE status = CreateIoCompletionPort(
    (HANDLE)handle,
    m_iocp,
    (ULONG_PTR)key,
    0
    );

    return status;
    }


    };

    // just for the windows test...
    // its in the win namespace anyway... ;^)
    #define CT_MACRO_QUOTE_0(mp_0)#mp_0 // rofl!
    #define CT_MACRO_QUOTE(mp_0)CT_MACRO_QUOTE_0(mp_0) // rofl!


    #define CT_IO_SYSTEM_L2_CACHE_LINE (128)


    #define CT_PER_IO_ALIGN_PAD (CT_IO_SYSTEM_L2_CACHE_LINE)

    #define CT_PER_IO_STATE_ACCEPT 0x1
    #define CT_PER_IO_STATE_CONNECT 0x2
    #define CT_PER_IO_STATE_DISCONNECT 0x4
    #define CT_PER_IO_STATE_RECV 0x8
    #define CT_PER_IO_STATE_SEND 0x10



    #define CT_PER_SOCKET_ALIGN_PAD (CT_IO_SYSTEM_L2_CACHE_LINE)
    #define CT_PER_SOCKET_BUFFER (CT_PER_SOCKET_ALIGN_PAD * 32)
    #define CT_PER_SOCKET_STATE_CONNECTED 0x1
    #define CT_PER_SOCKET_FROM_MALLOC 0x2

    // per_io always owned by a single thread at any one time...
    struct alignas(CT_PER_IO_ALIGN_PAD) per_io
    {
    struct per_io_raw
    {
    WSAOVERLAPPED m_ol;
    slist_node m_slist_node;
    per_io* m_next;
    struct per_socket* m_per_socket; // not totally nesserary... Humm...
    unsigned long m_state;

    unsigned char* m_buf;
    std::size_t m_buf_n;
    };


    per_io_raw m_raw;

    void ctor()
    {
    static_assert(offsetof(per_io, m_raw) == 0, "m_raw
    must be first!");
    static_assert(offsetof(per_io_raw, m_ol) == 0,
    "m_ol must be first!");

    m_raw = { };

    std::cout <<
    "(" << this << ")->"
    "ct::proxy_0_0_0_0::win::"
    "per_io::ctor()\n";
    }

    // not mandatory
    void dtor()
    {
    std::cout <<
    "(" << this << ")->"
    "ct::proxy_0_0_0_0::win::"
    "per_io::dtor()\n";
    }
    };

    static_assert(
    sizeof(per_io) == CT_PER_IO_ALIGN_PAD,
    "per_io pad error" CT_MACRO_QUOTE(CT_PER_IO_ALIGN_PAD)
    );




    struct alignas(CT_PER_IO_ALIGN_PAD) per_socket
    {
    struct buffer
    {
    unsigned char m_raw_buffer[CT_PER_SOCKET_BUFFER];
    };

    struct per_socket_raw
    {
    slist_node m_slist_node;
    per_socket* m_next;
    std::atomic<unsigned long> m_state;
    SOCKET m_socket;

    unsigned char* m_buf;
    std::size_t m_buf_n;

    alignas(CT_PER_IO_ALIGN_PAD) buffer m_raw_buffer;
    };

    per_socket_raw m_raw;

    void ctor()
    {
    m_raw.m_slist_node = { };
    m_raw.m_next = nullptr;
    m_raw.m_state.store(0, std::memory_order_relaxed);
    m_raw.m_socket = INVALID_SOCKET;
    m_raw.m_buf = m_raw.m_raw_buffer.m_raw_buffer;
    m_raw.m_buf_n = CT_PER_SOCKET_BUFFER;

    // well, init m_raw.m_raw_buffer ;^)
    m_raw.m_raw_buffer = { 0 };

    std::cout <<
    "(" << this << ")->"
    "ct::proxy_0_0_0_0::win::"
    "per_socket::ctor()\n";
    }

    void dtor()
    {
    if (m_raw.m_socket != INVALID_SOCKET)
    {
    SOCKET old_socket = m_raw.m_socket;
    m_raw.m_socket = INVALID_SOCKET;

    if (closesocket(old_socket))
    {
    // GOD DAMN IT!
    // fucking throw!
    // GRRRRR!
    // or extend ctor and dtor to return status
    // How C can you get in C++? ;^D
    return;
    }
    }

    std::cout <<
    "(" << this << ")->"
    "ct::proxy_0_0_0_0::win::"
    "per_socket::dtor()\n";
    }

    wsa_extensions
    get_wsaex()
    {
    wsa_extensions wsaex;
    wsaex.load(m_raw.m_socket);
    return wsaex;
    }

    };

    static_assert(
    sizeof(per_socket) == CT_PER_SOCKET_ALIGN_PAD + CT_PER_SOCKET_BUFFER &&
    sizeof(per_socket) % CT_PER_SOCKET_ALIGN_PAD == 0,
    "per_socket pad error" CT_MACRO_QUOTE(CT_PER_SOCKET_ALIGN_PAD)
    );

    template<typename T>
    struct single_threaded_stack
    {
    T* m_head = nullptr;

    void
    push(
    T* node
    ) {
    node->m_raw.m_next = m_head;
    m_head = node;
    }

    T*
    pop_try()
    {
    T* head = m_head;
    if (head)
    {
    m_head = head->m_raw.m_next;
    }
    return head;
    }
    };


    // abstract into io_system
    struct io_system
    {
    ct::proxy_0_0_0_0::win::winsock m_winsock;
    ct::proxy_0_0_0_0::win::iocp m_iocp;
    std::vector<unsigned char> m_raw_buffer;
    atomic_region m_atomic_region;

    single_threaded_stack<per_io> m_per_io_pool;
    single_threaded_stack<per_socket> m_per_socket_pool;

    // need to ponder...
    single_threaded_stack<per_socket> m_per_socket_active;




    struct io_worker
    {
    io_system& m_system;

    io_worker(
    io_system& system

    ) : m_system(system)
    {

    }


    int
    io_worker_loop()
    {
    return 0;
    }
    };


    // well might as well use a C++ ctor here...
    // ;^D
    io_system(
    std::size_t usable,
    std::size_t align,
    std::size_t prime_per_io_n,
    std::size_t prime_per_socket_n
    ): m_raw_buffer(usable + align - 1)
    {

    region raw_region = { };
    rinit(&raw_region, m_raw_buffer.data(), m_raw_buffer.size());

    unsigned char* aligned_buffer =
    static_cast<unsigned
    char*>(rallocex(&raw_region, usable, align));

    m_atomic_region.init(aligned_buffer, usable);

    // prime per-io
    {
    std::size_t n = prime_per_io_n;
    region pool_reg = create_region_from_atomic(sizeof(per_io) * n);
    for (int i = 0; i < n; ++i) {
    per_io* p = static_cast<per_io*>(rallocex(&pool_reg, sizeof(*p), CT_PER_IO_ALIGN_PAD));
    p->ctor(); // Ensure constructor is called
    m_per_io_pool.push(p);
    }
    }

    // prime per-socket
    {
    std::size_t n = prime_per_socket_n;
    region pool_reg = create_region_from_atomic(sizeof(per_socket) * n);
    for (int i = 0; i < n; ++i) {
    per_socket* p = static_cast<per_socket*>(rallocex(&pool_reg, sizeof(*p), CT_PER_SOCKET_ALIGN_PAD));
    p->ctor(); // Ensure constructor is called
    m_per_socket_pool.push(p);
    }
    }
    }

    ~io_system()
    {

    }


    region
    create_region_from_atomic(
    std::size_t usable
    ) {
    unsigned char* p = m_atomic_region.alloc(usable);
    if (! p)
    {
    // time to fly...
    return { nullptr };
    }

    region r = { };
    rinit(&r, p, usable);
    return r;
    }


    int
    create_accept(
    per_socket& listen_sock, // also renamed for consistency
    per_socket& accept_sock, // <--- demon slain
    per_io& pio
    ) {
    accept_sock.m_raw.m_socket = WSASocket(
    AF_INET, SOCK_STREAM, IPPROTO_TCP,
    nullptr, 0, WSA_FLAG_OVERLAPPED
    );

    if (accept_sock.m_raw.m_socket == INVALID_SOCKET)
    {
    std::cout << "create_accept WSASocket() failed: "
    << WSAGetLastError() << "\n";
    return 1;
    }

    std::cout << "accept_socket = " << accept_sock.m_raw.m_socket << "\n";

    pio.m_raw.m_buf = accept_sock.m_raw.m_buf;
    pio.m_raw.m_buf_n = accept_sock.m_raw.m_buf_n;

    pio.m_raw.m_per_socket = &accept_sock;
    pio.m_raw.m_state |= CT_PER_IO_STATE_ACCEPT;

    DWORD bytes_received = 0;

    BOOL ok = m_winsock.m_wsaex.m_acceptex(
    listen_sock.m_raw.m_socket,
    accept_sock.m_raw.m_socket,
    pio.m_raw.m_buf,
    0,
    sizeof(SOCKADDR_IN) + 16,
    sizeof(SOCKADDR_IN) + 16,
    &bytes_received,
    &pio.m_raw.m_ol
    );

    if (!ok && WSAGetLastError() != ERROR_IO_PENDING)
    {
    std::cout << "AcceptEx failed: " <<
    WSAGetLastError() << "\n";
    return 1;
    }

    std::cout << "AcceptEx posted!\n";
    return 0;
    }



    void
    complete_accept(
    per_socket& listen_sock, // renamed for
    consistency
    per_io& pio
    ) {
    {
    SOCKADDR* local_addr = nullptr;
    SOCKADDR* remote_addr = nullptr;
    int local_len = 0;
    int remote_len = 0;

    m_winsock.m_wsaex.m_getacceptexsockaddrs(
    pio.m_raw.m_buf,
    0,
    sizeof(SOCKADDR_IN) + 16,
    sizeof(SOCKADDR_IN) + 16,
    &local_addr,
    &local_len,
    &remote_addr,
    &remote_len
    );

    auto* local_in = reinterpret_cast<SOCKADDR_IN*>(local_addr);
    auto* remote_in = reinterpret_cast<SOCKADDR_IN*>(remote_addr);

    char addrbuf[INET6_ADDRSTRLEN] = { };

    InetNtopA(
    AF_INET,
    &remote_in->sin_addr,
    addrbuf,
    sizeof(addrbuf)
    );

    std::cout << "client connected from "
    << addrbuf << ":"
    << ntohs(remote_in->sin_port) << "\n";


    }

    // fix up the accepted socket
    int status = setsockopt(
    pio.m_raw.m_per_socket->m_raw.m_socket,
    SOL_SOCKET,
    SO_UPDATE_ACCEPT_CONTEXT,
    (char*)&listen_sock.m_raw.m_socket,
    sizeof(SOCKET)
    );

    if (status)
    {
    // oh fuck me!
    // throw; die die die! rofl. ;^D
    return;
    }

    pio.m_raw.m_per_socket->m_raw.m_state.store(
    CT_PER_SOCKET_STATE_CONNECTED,
    std::memory_order_relaxed
    );

    // zero buffer before bind? ;^D Don't even need to, but...
    pio.m_raw.m_per_socket->m_raw.m_raw_buffer = { 0 };

    // bind the sucker!
    m_iocp.bind(
    (HANDLE)pio.m_raw.m_per_socket->m_raw.m_socket,
    (ULONG_PTR)pio.m_raw.m_per_socket
    );
    }


    void
    create_listen(
    addr_info& addr_info_,
    per_socket& listen_sock
    ) {
    listen_sock.m_raw.m_socket = WSASocket(
    addr_info_.m_result->ai_family,
    addr_info_.m_result->ai_socktype,
    addr_info_.m_result->ai_protocol,
    nullptr, 0, WSA_FLAG_OVERLAPPED
    );

    if (listen_sock.m_raw.m_socket == INVALID_SOCKET)
    {
    std::cout << "WSASocket() for listen failed: "
    << WSAGetLastError() << "\n";
    return;
    }

    std::cout << "listen socket = " << listen_sock.m_raw.m_socket << "\n";

    m_winsock.m_wsaex.load(listen_sock.m_raw.m_socket);

    if (::bind(listen_sock.m_raw.m_socket, // explicit ::bind
    addr_info_.m_result->ai_addr,
    (int)addr_info_.m_result->ai_addrlen) == SOCKET_ERROR)
    {
    std::cout << "bind() failed: " <<
    WSAGetLastError() << "\n";
    return;
    }

    if (listen(listen_sock.m_raw.m_socket, SOMAXCONN)
    == SOCKET_ERROR)
    {
    std::cout << "listen() failed: " <<
    WSAGetLastError() << "\n";
    return;
    }

    if (!m_iocp.bind(
    (HANDLE)listen_sock.m_raw.m_socket,
    (ULONG_PTR)&listen_sock
    ))
    {
    std::cout << "IOCP associate failed: " << GetLastError() << "\n";
    return;
    }

    std::cout << "Listen socket fully set up.\n";
    }

    int
    issue_recv(
    per_socket& socket,
    per_io& pio
    ) {
    pio.m_raw.m_state |= CT_PER_IO_STATE_RECV;

    WSABUF wbuf;
    wbuf.buf = reinterpret_cast<char*>(pio.m_raw.m_buf);
    wbuf.len = static_cast<ULONG>(pio.m_raw.m_buf_n);

    DWORD flags = 0;
    DWORD bytes = 0;

    pio.m_raw.m_ol = WSAOVERLAPPED{};

    int rc = WSARecv(
    socket.m_raw.m_socket,
    &wbuf,
    1,
    &bytes,
    &flags,
    &pio.m_raw.m_ol,
    nullptr
    );

    if (rc == SOCKET_ERROR)
    {
    int err = WSAGetLastError();
    if (err != WSA_IO_PENDING)
    {
    std::cout << "WSARecv failed: " << err << "\n";
    return 1;
    }
    }

    std::cout << "WSARecv posted\n";
    return 0;

    }


    int
    issue_send(
    per_socket& socket,
    per_io& pio
    ) {

    // mark this IO as a send
    pio.m_raw.m_state |= CT_PER_IO_STATE_SEND;

    WSABUF wbuf;
    wbuf.buf = reinterpret_cast<char*>(pio.m_raw.m_buf);
    wbuf.len = static_cast<ULONG>(pio.m_raw.m_buf_n);

    DWORD bytes = 0;
    DWORD flags = 0;

    // reset OVERLAPPED for this op
    pio.m_raw.m_ol = WSAOVERLAPPED{};

    int rc = WSASend(
    socket.m_raw.m_socket,
    &wbuf,
    1,
    &bytes,
    flags,
    &pio.m_raw.m_ol,
    nullptr
    );

    if (rc == SOCKET_ERROR)
    {
    int err = WSAGetLastError();
    if (err != WSA_IO_PENDING)
    {
    std::cout << "WSASend failed: " << err << "\n";
    return 1;
    }
    }

    std::cout << "WSASend posted\n";
    return 0;

    }

    };



    }


    int
    manifest()
    {
    int manifest_state = 0;

    {
    std::cout <<
    "ct::proxy_0_0_0_0\n"
    "ver (0.0.0.0) (pre-alpha)\n"
    "by: Chris M. Thomasson\n"
    "____________________________________" <<
    std::endl;

    {
    // logic...

    std::size_t iosys_usable = 1024 * 1024;
    std::size_t iosys_prime_per_io = 16;
    std::size_t iosys_prime_per_socket = 16;
    std::size_t iosys_align = 8192;

    ct::proxy_0_0_0_0::win::io_system iosys(
    iosys_usable,
    iosys_align,
    iosys_prime_per_io,
    iosys_prime_per_socket
    );


    {
    struct ct::proxy_0_0_0_0::win::per_socket* psocket_listen =
    iosys.m_per_socket_pool.pop_try();

    if (! psocket_listen)
    {
    // oh fuck that!
    //throw; ;^D
    return 1;
    }

    ct::tools::dtor
    psocket_listen_raii(psocket_listen);

    std::cout << "psocket_listen = " <<
    psocket_listen << "\n";

    {
    ct::proxy_0_0_0_0::win::addr_info addr_info;
    iosys.create_listen(addr_info,
    *psocket_listen);

    struct ct::proxy_0_0_0_0::win::per_socket* psocket_accept =
    iosys.m_per_socket_pool.pop_try();

    ct::tools::dtor psocket_accept_raii(psocket_accept);

    std::cout << "psocket_accept = " << psocket_accept << "\n";

    {
    struct ct::proxy_0_0_0_0::win::per_io*
    pio0 =
    iosys.m_per_io_pool.pop_try();

    if (! pio0)
    {
    // oh fuck that!
    //throw; ;^D
    return 1;
    }

    std::cout << "pio0 = " << pio0 << "\n";



    iosys.create_accept(*psocket_listen, *psocket_accept, *pio0);

    {
    // ADD THIS!
    std::cout << "waiting... telnet
    localhost 8080!\n";

    // ;^D 42 hard code. Need to ponder.
    OVERLAPPED_ENTRY pol[42] = { { } };
    ULONG pol_n = 0;

    // only recv 1...
    DWORD s = iosys.m_iocp.gqcsex(pol,
    1, &pol_n, INFINITE);

    if (pol_n > 0)
    {
    // need a loop here... ;^) But

    ct::proxy_0_0_0_0::win::per_io*
    pio =

    (ct::proxy_0_0_0_0::win::per_io*)pol[0].lpOverlapped;

    std::cout << "socket match: "
    << (pio->m_raw.m_per_socket == psocket_accept ? "YES!!!" : "NO!!!") << "\n";
    }

    if (s == 0)
    {
    ct::proxy_0_0_0_0::win::per_io*
    pio =

    (ct::proxy_0_0_0_0::win::per_io*)pol[0].lpOverlapped;

    std::cout << "gqcsex fired!\n";
    std::cout << "pio = " << pio
    << "\n";
    std::cout << "pio0 = " << pio0
    << "\n";
    std::cout << "match: " << (pio
    == pio0 ? "YES!!!" : "NO!!!") << "\n";
    std::cout << "WE HAVE A CONNECTION!!!\n";

    if (pio->m_raw.m_state & CT_PER_IO_STATE_ACCEPT)
    {
    std::cout << "accepted
    per_socket " << pio->m_raw.m_per_socket << "\n";



    iosys.complete_accept(*psocket_listen, *pio);


    std::cout << "CT_PER_IO_STATE_ACCEPT\n";

    // pio->m_raw.m_per_socket->issue_wsa_recv(*pio);

    iosys.issue_recv(*pio->m_raw.m_per_socket, *pio);
    }
    }
    }
    }
    }
    }
    }

    std::cout <<
    "manifest_state = " << manifest_state << "\n";

    std::cout << "____________________________________" <<
    std::endl;
    }


    return manifest_state;
    }
    }
    }




    int main()
    {
    int main_state = 0;

    std::cout <<
    "ct_proxy\n"
    "ver (0.0.0.0) (pre-alpha)\n"
    "by: Chris M. Thomasson\n"
    "getting back to my old IOCP work...\n"
    "________________________________________________\n" <<
    std::endl;

    {
    int state = ct::proxy_0_0_0_0::manifest();

    {
    // ponder on state. Some failures can be success... ;^)
    }

    main_state = state;
    }

    std::cout <<
    "\n________________________________________________\n" <<
    "main_state = " << main_state <<
    "\nfin" <<
    std::endl;

    return EXIT_SUCCESS;
    }




    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Chris M. Thomasson@3:633/10 to All on Fri Jul 3 12:45:36 2026
    On 7/3/2026 12:44 PM, Chris M. Thomasson wrote:
    [...]


    Fwiw, here is my ct_ralloc.hpp:


    #if ! defined (RALLOC_H)
    # define RALLOC_H
    # if defined (__cplusplus)
    extern "C" {
    # endif
    /**************************************************************/




    #include <cstddef>
    #include <cassert>




    #if defined (_MSC_VER)
    /* warning C4116: unnamed type definition in parentheses */
    # pragma warning (disable : 4116)
    #endif




    #if ! defined (NDEBUG)
    # include <cstdio>
    # define RALLOC_DBG_PRINTF(mp_exp) std::printf mp_exp
    #else
    # define RALLOC_DBG_PRINTF(mp_exp) ((void)0)
    #endif




    #if ! defined (RALLOC_UINTPTR_TYPE)
    # define RALLOC_UINTPTR_TYPE size_t
    #endif




    typedef RALLOC_UINTPTR_TYPE ralloc_uintptr_type;


    typedef char ralloc_static_assert[
    sizeof(ralloc_uintptr_type) == sizeof(void*) ? 1 : -1
    ];


    #define RALLOC_ALIGN_OF(mp_type) alignof(mp_type)
    #define RALLOC_ALIGN_MAX alignof(std::max_align_t)


    #define RALLOC_ALIGN_UP(mp_ptr, mp_align) \
    ((void*)( \
    (((ralloc_uintptr_type)(mp_ptr)) + ((mp_align) - 1)) \
    & ~(((mp_align) - 1)) \
    ))


    #define RALLOC_ALIGN_ASSERT(mp_ptr, mp_align) \
    (((void*)(mp_ptr)) == RALLOC_ALIGN_UP(mp_ptr, mp_align))




    struct region {
    unsigned char* buffer;
    size_t size;
    size_t offset;
    };


    static void
    rinit(
    struct region* const self,
    void* buffer,
    size_t size
    ) {
    self->buffer = (unsigned char*)buffer;
    self->size = size;
    self->offset = 0;

    RALLOC_DBG_PRINTF((
    "rinit(%p) {\n"
    " buffer = %p\n"
    " size = %lu\n"
    "}\n\n\n",
    (void*)self,
    buffer,
    (unsigned long int)size
    ));
    }


    static void*
    rallocex(
    struct region* const self,
    size_t size,
    size_t align
    ) {
    unsigned char* align_buffer;
    size_t offset = self->offset;
    unsigned char* raw_buffer = self->buffer + offset;

    if (! size) {
    size = 1;
    }

    if (! align) {
    align = RALLOC_ALIGN_MAX;
    }

    assert(align == 1 || RALLOC_ALIGN_ASSERT(align, 2));

    align_buffer = (unsigned char*)RALLOC_ALIGN_UP(raw_buffer, align);

    assert(RALLOC_ALIGN_ASSERT(align_buffer, align));

    size += align_buffer - raw_buffer;

    if (offset + size > self->size) {
    return NULL;
    }

    self->offset = offset + size;

    RALLOC_DBG_PRINTF((
    "rallocex(%p) {\n"
    " size = %llu\n"
    " alignment = %llu\n"
    " origin offset = %llu\n"
    " final offset = %llu\n"
    " raw_buffer = %p\n"
    " align_buffer = %p\n"
    " size adjustment = %llu\n"
    " final size = %llu\n"
    "}\n\n\n",
    (void*)self,
    (unsigned long long int)size - (align_buffer - raw_buffer),
    (unsigned long long int)align,
    (unsigned long long int)offset,
    (unsigned long long int)self->offset,
    (void*)raw_buffer,
    (void*)align_buffer,
    (unsigned long long int)(align_buffer - raw_buffer),
    (unsigned long long int)size
    ));

    return align_buffer;
    }


    #define ralloc(mp_self, mp_size) \
    rallocex((mp_self), (mp_size), RALLOC_ALIGN_MAX)

    #define ralloct(mp_self, mp_count, mp_type) \
    rallocex( \
    (mp_self), \
    sizeof(mp_type) * (mp_count),\
    RALLOC_ALIGN_OF(mp_type) \
    )


    static void
    rflush(
    struct region* const self
    ) {
    self->offset = 0;

    RALLOC_DBG_PRINTF((
    "rflush(%p) {}\n\n\n",
    (void*)self
    ));
    }




    #undef RALLOC_DBG_PRINTF
    #undef RALLOC_UINTPTR_TYPE




    /**************************************************************/
    # if defined (__cplusplus)
    }
    # endif
    #endif






    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From boltar@3:633/10 to All on Sat Jul 4 09:16:11 2026
    On Fri, 3 Jul 2026 12:44:07 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/3/2026 1:59 AM, boltar@caprica.universe wrote:
    I'd hate to see your code, must be an overcomplicated mess.


    Set your coffee down! Here is my raw test for my mind trying to sketch
    out an IOCP server setup from my memory... It should compile for you, I

    Are you seriously expecting me to believe you spent a morning writing the
    1200 lines of code below from memory? Oh please.

    Also it looks like win32 code and AFAIK windows for [reasons] can't do multiplexing on sockets so you have the ridiculous situation of needing a thread per connection whether you like it or not.

    will show my ralloc code in follow up. I had a little trouble

    Don't bother, don't care, I have better things to do than wade through all
    that code. Provide a 20 line example of "simple" thread pools and I might
    be interested.



    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Chris M. Thomasson@3:633/10 to All on Sat Jul 4 17:32:07 2026
    On 7/4/2026 2:16 AM, boltar@caprica.universe wrote:
    On Fri, 3 Jul 2026 12:44:07 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/3/2026 1:59 AM, boltar@caprica.universe wrote:
    I'd hate to see your code, must be an overcomplicated mess.


    Set your coffee down! Here is my raw test for my mind trying to sketch
    out an IOCP server setup from my memory... It should compile for you, I

    Are you seriously expecting me to believe you spent a morning writing the 1200 lines of code below from memory? Oh please.

    Several days on some free time, yes, from memory.


    Also it looks like win32 code and AFAIK windows for [reasons] can't do multiplexing on sockets so you have the ridiculous situation of needing a thread per connection whether you like it or not.

    Huh? When is the last time you used GetQueuedCompletionStatusEx?


    will show my ralloc code in follow up. I had a little trouble

    Don't bother, don't care, I have better things to do than wade through all that code. Provide a 20 line example of "simple" thread pools and I might
    be interested.


    My ralloc code? Its pretty old! Yet works like a charm.

    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Chris M. Thomasson@3:633/10 to All on Sat Jul 4 17:35:24 2026
    On 7/4/2026 5:32 PM, Chris M. Thomasson wrote:
    On 7/4/2026 2:16 AM, boltar@caprica.universe wrote:
    On Fri, 3 Jul 2026 12:44:07 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/3/2026 1:59 AM, boltar@caprica.universe wrote:
    I'd hate to see your code, must be an overcomplicated mess.


    Set your coffee down! Here is my raw test for my mind trying to
    sketch out an IOCP server setup from my memory... It should compile
    for you, I

    Are you seriously expecting me to believe you spent a morning writing the
    1200 lines of code below from memory? Oh please.

    Several days on some free time, yes, from memory.


    Also it looks like win32 code and AFAIK windows for [reasons] can't do
    multiplexing on sockets so you have the ridiculous situation of needing a
    thread per connection whether you like it or not.

    Huh? When is the last time you used GetQueuedCompletionStatusEx?


    will show my ralloc code in follow up. I had a little trouble

    Don't bother, don't care, I have better things to do than wade through
    all
    that code. Provide a 20 line example of "simple" thread pools and I might
    be interested.


    My ralloc code? Its pretty old! Yet works like a charm.

    Olivia Newton John - Magic (live on the midnight special)

    https://youtu.be/J3_uO5Fa8Oo?list=RDJ3_uO5Fa8Oo

    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Chris M. Thomasson@3:633/10 to All on Sat Jul 4 23:36:09 2026
    On 7/3/2026 1:59 AM, boltar@caprica.universe wrote:
    On Thu, 2 Jul 2026 11:41:48 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/2/2026 1:13 AM, boltar@caprica.universe wrote:
    They're hard enough to make it a lot of pointless work if its not
    necessary. As I said, if you're creating threads every few
    milliseconds then
    use a thread pool. If you're just creating a thread every few seconds
    or longer then a pool is a complete waste of time.

    Thread per connection model? If that works for your work load, so be
    it. Just don't be alarmed if you get 10000 threads all of sudden. Or,
    say a connection comes in every second for say a half an hour. 1800
    connections? Also you need to think about a connection that sends a
    little data then just sits there doing nothing for say 20 minutes.

    You do realise setting up and pulling down a TCP connection takes far more CPU resources than simply adding a new program counter into the scheduler list, right? If we were talking about creating a new process via fork()
    then
    your argument might have some merit, but threads? No.

    Why destroy the socket? Reuse it:

    TF_REUSE_SOCKET

    https://learn.microsoft.com/en-us/windows/win32/api/mswsock/nc-mswsock-lpfn_disconnectex

    [...]

    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Chris M. Thomasson@3:633/10 to All on Sat Jul 4 23:47:27 2026
    On 6/30/2026 1:29 PM, Michael S wrote:
    On Tue, 30 Jun 2026 10:27:38 +0200
    Wuns Haerst <Wuns.Haerst@wurstfabrik.at> wrote:

    I measured the time it takes to create a thread on both Windows and
    Linux. On Windows, it takes around 120,000 clock cycles, whereas on
    Linux, it takes about a third of that.
    It occurred to me that one could simply inline the thread's main
    function. This would eliminate the need for the operating system
    call to create the thread. In this scenario, the compiler ? or its
    runtime ? would have to handle the scheduling.
    I estimate that this would reduce the thread creation overhead to
    just a few clock cycles, making thread pools unnecessary. I?m just
    not sure yet exactly how to go about implementing this. Perhaps
    someone here can help me with it.
    Please send any relevant suggestions via email only, as I intend
    to patent this idea once it is fully developed.

    In majority of situations you don't need to create threads on Window.
    Use one of the several available Windows thread pool APIs.
    For example, QueueUserWorkItem() - somewhat outdated and not
    feature-rich, but very easy to use.

    Of course, in C++ group it is of topic, because it does not map itself
    well into C++ std::thread model. But that should not stop you if it is
    a right answer to youur needs.


    C++ and std::thread work pretty damn nice, basically akin to POSIX
    threads, well wrt the C11. But, C++ works fine.

    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From boltar@3:633/10 to All on Sun Jul 5 08:19:05 2026
    On Sat, 4 Jul 2026 17:32:07 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/4/2026 2:16 AM, boltar@caprica.universe wrote:
    On Fri, 3 Jul 2026 12:44:07 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/3/2026 1:59 AM, boltar@caprica.universe wrote:
    I'd hate to see your code, must be an overcomplicated mess.


    Set your coffee down! Here is my raw test for my mind trying to sketch
    out an IOCP server setup from my memory... It should compile for you, I

    Are you seriously expecting me to believe you spent a morning writing the
    1200 lines of code below from memory? Oh please.

    Several days on some free time, yes, from memory.

    What an exiting life you must have.

    Also it looks like win32 code and AFAIK windows for [reasons] can't do
    multiplexing on sockets so you have the ridiculous situation of needing a
    thread per connection whether you like it or not.

    Huh? When is the last time you used GetQueuedCompletionStatusEx?

    Never even heard of it. Can it also multiplex file descriptors + std in,out,err in the same call like select() or poll()? No, didn't think so, so you'll still need multiple threads if you want to do all at the same time. Good old half assed win32.

    Don't bother, don't care, I have better things to do than wade through all >> that code. Provide a 20 line example of "simple" thread pools and I might
    be interested.


    My ralloc code? Its pretty old! Yet works like a charm.

    So show a short example in 20 lines or less then if its as "simple" as you claim.


    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From boltar@3:633/10 to All on Sun Jul 5 08:21:15 2026
    On Sat, 4 Jul 2026 23:36:09 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/3/2026 1:59 AM, boltar@caprica.universe wrote:
    On Thu, 2 Jul 2026 11:41:48 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/2/2026 1:13 AM, boltar@caprica.universe wrote:
    They're hard enough to make it a lot of pointless work if its not
    necessary. As I said, if you're creating threads every few
    milliseconds then
    use a thread pool. If you're just creating a thread every few seconds >>>> or longer then a pool is a complete waste of time.

    Thread per connection model? If that works for your work load, so be
    it. Just don't be alarmed if you get 10000 threads all of sudden. Or,
    say a connection comes in every second for say a half an hour. 1800
    connections? Also you need to think about a connection that sends a
    little data then just sits there doing nothing for say 20 minutes.

    You do realise setting up and pulling down a TCP connection takes far more >> CPU resources than simply adding a new program counter into the scheduler
    list, right? If we were talking about creating a new process via fork()
    then
    your argument might have some merit, but threads? No.

    Why destroy the socket? Reuse it:

    TF_REUSE_SOCKET

    https://learn.microsoft.com/en-us/windows/win32/api/mswsock/nc-mswsock-lpfn_dis
    connectex

    I'm not interesting in win32, I only do posix and in posix a socket is simply an (indirect) integer index into a kernel network connection. Re-using one after

    the network connection has been closed makes no sense.


    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Chris M. Thomasson@3:633/10 to All on Sun Jul 5 01:21:56 2026
    On 7/5/2026 1:19 AM, boltar@caprica.universe wrote:
    On Sat, 4 Jul 2026 17:32:07 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/4/2026 2:16 AM, boltar@caprica.universe wrote:
    On Fri, 3 Jul 2026 12:44:07 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/3/2026 1:59 AM, boltar@caprica.universe wrote:
    I'd hate to see your code, must be an overcomplicated mess.


    Set your coffee down! Here is my raw test for my mind trying to
    sketch out an IOCP server setup from my memory... It should compile
    for you, I

    Are you seriously expecting me to believe you spent a morning writing
    the
    1200 lines of code below from memory? Oh please.

    Several days on some free time, yes, from memory.

    What an exiting life you must have.

    Also it looks like win32 code and AFAIK windows for [reasons] can't do
    multiplexing on sockets so you have the ridiculous situation of
    needing a
    thread per connection whether you like it or not.

    Huh? When is the last time you used GetQueuedCompletionStatusEx?

    Never even heard of it. Can it also multiplex file descriptors + std in,out,err
    in the same call like select() or poll()? No, didn't think so, so you'll still
    need multiple threads if you want to do all at the same time. Good old half assed win32.

    Huh? It can work with SOCKETS and FILES.


    Don't bother, don't care, I have better things to do than wade
    through all
    that code. Provide a 20 line example of "simple" thread pools and I
    might
    be interested.


    My ralloc code? Its pretty old! Yet works like a charm.

    So show a short example in 20 lines or less then if its as "simple" as you claim.


    Huh? My ralloc code or a thread pool?

    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Chris M. Thomasson@3:633/10 to All on Sun Jul 5 01:22:34 2026
    On 7/5/2026 1:21 AM, boltar@caprica.universe wrote:
    On Sat, 4 Jul 2026 23:36:09 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/3/2026 1:59 AM, boltar@caprica.universe wrote:
    On Thu, 2 Jul 2026 11:41:48 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/2/2026 1:13 AM, boltar@caprica.universe wrote:
    They're hard enough to make it a lot of pointless work if its not
    necessary. As I said, if you're creating threads every few
    milliseconds then
    use a thread pool. If you're just creating a thread every few
    seconds or longer then a pool is a complete waste of time.

    Thread per connection model? If that works for your work load, so be
    it. Just don't be alarmed if you get 10000 threads all of sudden.
    Or, say a connection comes in every second for say a half an hour.
    1800 connections? Also you need to think about a connection that
    sends a little data then just sits there doing nothing for say 20
    minutes.

    You do realise setting up and pulling down a TCP connection takes far
    more
    CPU resources than simply adding a new program counter into the
    scheduler
    list, right? If we were talking about creating a new process via
    fork() then
    your argument might have some merit, but threads? No.

    Why destroy the socket? Reuse it:

    TF_REUSE_SOCKET

    https://learn.microsoft.com/en-us/windows/win32/api/mswsock/nc-
    mswsock-lpfn_dis
    connectex

    I'm not interesting in win32, I only do posix and in posix a socket is simply
    an (indirect) integer index into a kernel network connection. Re-using
    one after

    the network connection has been closed makes no sense.


    Why? TF_REUSE_SOCKET is VERY useful.

    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Bonita Montero@3:633/10 to All on Sun Jul 5 14:03:33 2026
    Am 30.06.2026 um 17:25 schrieb Scott Lurndal:

    How do you know how the oracle RDBMS works internally?

    It's not documented but a lot of people have guessed that. Oracle
    allows it to limit the absolute CPU-time of a session, a user or
    a consumer group. With Windows this isn't possible so you have
    to do our own userspace schedulung. With Linux it's possible
    since Linux has control groups, but Oracle predates this feature.


    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Scott Lurndal@3:633/10 to All on Sun Jul 5 14:39:45 2026
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> writes:
    On 7/5/2026 1:21 AM, boltar@caprica.universe wrote:

    I'm not interesting in win32, I only do posix and in posix a socket is
    simply
    an (indirect) integer index into a kernel network connection. Re-using
    one after

    the network connection has been closed makes no sense.


    Why? TF_REUSE_SOCKET is VERY useful.

    Posix has SO_REUSEADDR and SO_REUSEPORT for socket reuse.

    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Scott Lurndal@3:633/10 to All on Sun Jul 5 14:41:52 2026
    Bonita Montero <Bonita.Montero@gmail.com> writes:
    Am 30.06.2026 um 17:25 schrieb Scott Lurndal:

    How do you know how the oracle RDBMS works internally?

    It's not documented but a lot of people have guessed that.

    So you don't know.

    Oracle
    allows it to limit the absolute CPU-time of a session, a user or
    a consumer group. With Windows this isn't possible so you have
    to do our own userspace schedulung. With Linux it's possible
    since Linux has control groups, but Oracle predates this feature.


    Process resource limits have been available in Unix since before
    DOS morphed into windows 3.1.

    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From boltar@3:633/10 to All on Sun Jul 5 15:48:15 2026
    On Sun, 5 Jul 2026 01:21:56 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/5/2026 1:19 AM, boltar@caprica.universe wrote:
    On Sat, 4 Jul 2026 17:32:07 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/4/2026 2:16 AM, boltar@caprica.universe wrote:
    On Fri, 3 Jul 2026 12:44:07 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/3/2026 1:59 AM, boltar@caprica.universe wrote:
    I'd hate to see your code, must be an overcomplicated mess.


    Set your coffee down! Here is my raw test for my mind trying to
    sketch out an IOCP server setup from my memory... It should compile >>>>> for you, I

    Are you seriously expecting me to believe you spent a morning writing >>>> the
    1200 lines of code below from memory? Oh please.

    Several days on some free time, yes, from memory.

    What an exiting life you must have.

    Also it looks like win32 code and AFAIK windows for [reasons] can't do >>>> multiplexing on sockets so you have the ridiculous situation of
    needing a
    thread per connection whether you like it or not.

    Huh? When is the last time you used GetQueuedCompletionStatusEx?

    Never even heard of it. Can it also multiplex file descriptors + std
    in,out,err
    in the same call like select() or poll()? No, didn't think so, so you'll
    still
    need multiple threads if you want to do all at the same time. Good old half >> assed win32.

    Huh? It can work with SOCKETS and FILES.

    Well thats nice. What about pipes, fifos and character and block devices?
    Of course if they'd use the interface that was standard even when they were developing win32 it would have been more useful.

    So show a short example in 20 lines or less then if its as "simple" as you >> claim.


    Huh? My ralloc code or a thread pool?

    A thread pool, I have no idea what your ralloc code is supposed to do and I couldn't care less about it. You were claiming thread pools are easy to implement so lets see a nice easy example.


    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From boltar@3:633/10 to All on Sun Jul 5 15:49:06 2026
    On Sun, 5 Jul 2026 01:22:34 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/5/2026 1:21 AM, boltar@caprica.universe wrote:
    On Sat, 4 Jul 2026 23:36:09 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/3/2026 1:59 AM, boltar@caprica.universe wrote:
    On Thu, 2 Jul 2026 11:41:48 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/2/2026 1:13 AM, boltar@caprica.universe wrote:
    They're hard enough to make it a lot of pointless work if its not >>>>>> necessary. As I said, if you're creating threads every few
    milliseconds then
    use a thread pool. If you're just creating a thread every few
    seconds or longer then a pool is a complete waste of time.

    Thread per connection model? If that works for your work load, so be >>>>> it. Just don't be alarmed if you get 10000 threads all of sudden.
    Or, say a connection comes in every second for say a half an hour.
    1800 connections? Also you need to think about a connection that
    sends a little data then just sits there doing nothing for say 20
    minutes.

    You do realise setting up and pulling down a TCP connection takes far >>>> more
    CPU resources than simply adding a new program counter into the
    scheduler
    list, right? If we were talking about creating a new process via
    fork() then
    your argument might have some merit, but threads? No.

    Why destroy the socket? Reuse it:

    TF_REUSE_SOCKET

    https://learn.microsoft.com/en-us/windows/win32/api/mswsock/nc-
    mswsock-lpfn_dis
    connectex

    I'm not interesting in win32, I only do posix and in posix a socket is
    simply
    an (indirect) integer index into a kernel network connection. Re-using
    one after

    the network connection has been closed makes no sense.


    Why? TF_REUSE_SOCKET is VERY useful.

    Why? Once its down a socket - in unix - is just an integer pointing to nothing. What difference does it make if the same value gets reused?


    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From boltar@3:633/10 to All on Sun Jul 5 15:50:36 2026
    On Sun, 05 Jul 2026 14:39:45 GMT
    scott@slp53.sl.home (Scott Lurndal) gabbled:
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> writes:
    On 7/5/2026 1:21 AM, boltar@caprica.universe wrote:

    I'm not interesting in win32, I only do posix and in posix a socket is
    simply
    an (indirect) integer index into a kernel network connection. Re-using
    one after

    the network connection has been closed makes no sense.


    Why? TF_REUSE_SOCKET is VERY useful.

    Posix has SO_REUSEADDR and SO_REUSEPORT for socket reuse.

    Thats not socket re-use, thats allowing a new listen socket to connect to the same interface address and port number before the previous one has been completely torn down.


    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Bonita Montero@3:633/10 to All on Sun Jul 5 20:08:33 2026
    Am 05.07.2026 um 16:41 schrieb Scott Lurndal:

    Bonita Montero <Bonita.Montero@gmail.com> writes:

    It's not documented but a lot of people have guessed that.

    So you don't know.

    I'm not the only one wo assumes that; it's not possible otherwise.

    Oracle
    allows it to limit the absolute CPU-time of a session, a user or
    a consumer group. With Windows this isn't possible so you have
    to do our own userspace schedulung. With Linux it's possible
    since Linux has control groups, but Oracle predates this feature.

    Process resource limits have been available in Unix since before
    DOS morphed into windows 3.1.

    You can set absolute limits with that, but not fractions of the
    number of cores. Applying the latter is possible since Linux has
    control groups and Windows has no option like that so far.

    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Chris M. Thomasson@3:633/10 to All on Sun Jul 5 13:01:07 2026
    On 7/5/2026 8:48 AM, boltar@caprica.universe wrote:
    On Sun, 5 Jul 2026 01:21:56 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/5/2026 1:19 AM, boltar@caprica.universe wrote:
    On Sat, 4 Jul 2026 17:32:07 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/4/2026 2:16 AM, boltar@caprica.universe wrote:
    On Fri, 3 Jul 2026 12:44:07 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/3/2026 1:59 AM, boltar@caprica.universe wrote:
    I'd hate to see your code, must be an overcomplicated mess.


    Set your coffee down! Here is my raw test for my mind trying to
    sketch out an IOCP server setup from my memory... It should
    compile for you, I

    Are you seriously expecting me to believe you spent a morning
    writing the
    1200 lines of code below from memory? Oh please.

    Several days on some free time, yes, from memory.

    What an exiting life you must have.

    Also it looks like win32 code and AFAIK windows for [reasons] can't do >>>>> multiplexing on sockets so you have the ridiculous situation of
    needing a
    thread per connection whether you like it or not.

    Huh? When is the last time you used GetQueuedCompletionStatusEx?

    Never even heard of it. Can it also multiplex file descriptors + std
    in,out,err
    in the same call like select() or poll()? No, didn't think so, so
    you'll still
    need multiple threads if you want to do all at the same time. Good
    old half
    assed win32.

    Huh? It can work with SOCKETS and FILES.

    Well thats nice. What about pipes, fifos and character and block devices?
    Of course if they'd use the interface that was standard even when they
    were developing win32 it would have been more useful.

    So show a short example in 20 lines or less then if its as "simple"
    as you
    claim.


    Huh? My ralloc code or a thread pool?

    A thread pool, I have no idea what your ralloc code is supposed to do and I couldn't care less about it. You were claiming thread pools are easy to implement so lets see a nice easy example.


    A thread pool in 20 lines? You mean to init the sucker and use it as the
    user right? Not the guts, its going to take more than that. The logic is straightforward to me. Yeah, its not that hard because I have made so
    many of them in the past.

    I need to make one for my from memory wrt the iocp test anyway. Heck my io_worker in its current state is:
    ________________
    struct io_worker
    {
    io_system& m_system;

    io_worker(
    io_system& system

    ) : m_system(system)
    {

    }


    int
    io_worker_loop()
    {
    return 0;
    }
    };
    ________________


    It needs a intrusive link to allow it to be inserted into an intrusive
    linked list.

    So perhaps:

    struct io_worker
    {
    io_worker* m_next; // hello!
    io_system& m_system;

    io_worker(
    io_system& system

    ) : m_system(system)
    {

    }


    int
    io_worker_loop()
    {
    return 0;
    }
    };



    Oh my another line.

    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Chris M. Thomasson@3:633/10 to All on Sun Jul 5 13:05:35 2026
    On 7/5/2026 11:08 AM, Bonita Montero wrote:
    Am 05.07.2026 um 16:41 schrieb Scott Lurndal:

    Bonita Montero <Bonita.Montero@gmail.com> writes:

    It's not documented but a lot of people have guessed that.

    So you don't know.

    I'm not the only one wo assumes that; it's not possible otherwise.

    Oracle
    allows it to limit the absolute CPU-time of a session, a user or
    a consumer group. With Windows this isn't possible so you have
    to do our own userspace schedulung. With Linux it's possible
    since Linux has control groups, but Oracle predates this feature.

    Process resource limits have been available in Unix since before
    DOS morphed into windows 3.1.

    You can set absolute limits with that, but not fractions of the
    number of cores. Applying the latter is possible since Linux has
    control groups and Windows has no option like that so far.

    https://learn.microsoft.com/en-us/windows/win32/procthread/processor-groups

    Kind a, sort a?

    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Chris M. Thomasson@3:633/10 to All on Sun Jul 5 13:16:11 2026
    On 7/5/2026 8:48 AM, boltar@caprica.universe wrote:
    On Sun, 5 Jul 2026 01:21:56 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/5/2026 1:19 AM, boltar@caprica.universe wrote:
    On Sat, 4 Jul 2026 17:32:07 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/4/2026 2:16 AM, boltar@caprica.universe wrote:
    On Fri, 3 Jul 2026 12:44:07 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/3/2026 1:59 AM, boltar@caprica.universe wrote:
    I'd hate to see your code, must be an overcomplicated mess.


    Set your coffee down! Here is my raw test for my mind trying to
    sketch out an IOCP server setup from my memory... It should
    compile for you, I

    Are you seriously expecting me to believe you spent a morning
    writing the
    1200 lines of code below from memory? Oh please.

    Several days on some free time, yes, from memory.

    What an exiting life you must have.

    Also it looks like win32 code and AFAIK windows for [reasons] can't do >>>>> multiplexing on sockets so you have the ridiculous situation of
    needing a
    thread per connection whether you like it or not.

    Huh? When is the last time you used GetQueuedCompletionStatusEx?

    Never even heard of it. Can it also multiplex file descriptors + std
    in,out,err
    in the same call like select() or poll()? No, didn't think so, so
    you'll still
    need multiple threads if you want to do all at the same time. Good
    old half
    assed win32.

    Huh? It can work with SOCKETS and FILES.

    Well thats nice. What about pipes, fifos and character and block devices?
    Of course if they'd use the interface that was standard even when they
    were developing win32 it would have been more useful.

    So show a short example in 20 lines or less then if its as "simple"
    as you
    claim.


    Huh? My ralloc code or a thread pool?

    A thread pool, I have no idea what your ralloc code is supposed to do and I couldn't care less about it. You were claiming thread pools are easy to implement so lets see a nice easy example.


    Also... If you think that over 20 lines is complicated, well... You
    would be fired on the spot?

    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Chris M. Thomasson@3:633/10 to All on Sun Jul 5 13:22:07 2026
    On 7/3/2026 8:59 AM, boltar@caprica.universe wrote:
    On Fri, 03 Jul 2026 14:41:29 GMT
    scott@slp53.sl.home (Scott Lurndal) gabbled:
    boltar@caprica.universe writes:
    On Thu, 2 Jul 2026 11:41:48 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:

    Thread per connection model? If that works for your work load, so be it. >>>> Just don't be alarmed if you get 10000 threads all of sudden. Or, say a >>>> connection comes in every second for say a half an hour. 1800
    connections? Also you need to think about a connection that sends a
    little data then just sits there doing nothing for say 20 minutes.

    You do realise setting up and pulling down a TCP connection takes far more >>> CPU resources than simply adding a new program counter into the scheduler >>> list, right?

    You're clearly not an expert on operating systems. There's far
    more involved than "simply adding a new program counter to the scheduler list"
    during thread creation.

    Actually there isn't that much more but if you think otherwise do fill us in on the details.


    Why don't you fill us in on the details? We already know, but you? Humm....

    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Chris M. Thomasson@3:633/10 to All on Sun Jul 5 14:03:01 2026
    On 7/5/2026 1:05 PM, Chris M. Thomasson wrote:
    On 7/5/2026 11:08 AM, Bonita Montero wrote:
    Am 05.07.2026 um 16:41 schrieb Scott Lurndal:

    Bonita Montero <Bonita.Montero@gmail.com> writes:

    It's not documented but a lot of people have guessed that.

    So you don't know.

    I'm not the only one wo assumes that; it's not possible otherwise.

    Oracle
    allows it to limit the absolute CPU-time of a session, a user or
    a consumer group. With Windows this isn't possible so you have
    to do our own userspace schedulung. With Linux it's possible
    since Linux has control groups, but Oracle predates this feature.

    Process resource limits have been available in Unix since before
    DOS morphed into windows 3.1.

    You can set absolute limits with that, but not fractions of the
    number of cores. Applying the latter is possible since Linux has
    control groups and Windows has no option like that so far.

    https://learn.microsoft.com/en-us/windows/win32/procthread/processor-groups

    Kind a, sort a?

    https://learn.microsoft.com/en-us/windows/win32/procthread/numa-support

    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Chris M. Thomasson@3:633/10 to All on Sun Jul 5 14:36:17 2026
    On 7/5/2026 11:08 AM, Bonita Montero wrote:
    Am 05.07.2026 um 16:41 schrieb Scott Lurndal:

    Bonita Montero <Bonita.Montero@gmail.com> writes:

    It's not documented but a lot of people have guessed that.

    So you don't know.

    I'm not the only one wo assumes that; it's not possible otherwise.

    Oracle
    allows it to limit the absolute CPU-time of a session, a user or
    a consumer group. With Windows this isn't possible so you have
    to do our own userspace schedulung. With Linux it's possible
    since Linux has control groups, but Oracle predates this feature.

    Process resource limits have been available in Unix since before
    DOS morphed into windows 3.1.

    You can set absolute limits with that, but not fractions of the
    number of cores. Applying the latter is possible since Linux has
    control groups and Windows has no option like that so far.

    https://learn.microsoft.com/en-us/windows/win32/procthread/cpu-sets

    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From boltar@3:633/10 to All on Mon Jul 6 09:28:29 2026
    On Sun, 5 Jul 2026 13:01:07 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/5/2026 8:48 AM, boltar@caprica.universe wrote:
    A thread pool, I have no idea what your ralloc code is supposed to do and I >> couldn't care less about it. You were claiming thread pools are easy to
    implement so lets see a nice easy example.


    A thread pool in 20 lines? You mean to init the sucker and use it as the >user right? Not the guts, its going to take more than that. The logic is >straightforward to me. Yeah, its not that hard because I have made so
    many of them in the past.

    Oh right, so not quite as simple as:

    thread mythread(....)
    mythread.detach()

    then as you were claiming. Glad we finally cleared that up.



    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From boltar@3:633/10 to All on Mon Jul 6 09:29:18 2026
    On Sun, 5 Jul 2026 13:16:11 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/5/2026 8:48 AM, boltar@caprica.universe wrote:
    A thread pool, I have no idea what your ralloc code is supposed to do and I >> couldn't care less about it. You were claiming thread pools are easy to
    implement so lets see a nice easy example.


    Also... If you think that over 20 lines is complicated, well... You
    would be fired on the spot?

    You were claiming thread pools are so simple to implement why would anyone
    not use them. So lets see this simple code of yours, not just some class framework without the details.


    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From boltar@3:633/10 to All on Mon Jul 6 09:29:38 2026
    On Sun, 5 Jul 2026 13:22:07 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/3/2026 8:59 AM, boltar@caprica.universe wrote:
    On Fri, 03 Jul 2026 14:41:29 GMT
    scott@slp53.sl.home (Scott Lurndal) gabbled:
    boltar@caprica.universe writes:
    On Thu, 2 Jul 2026 11:41:48 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:

    Thread per connection model? If that works for your work load, so be it. >>>>> Just don't be alarmed if you get 10000 threads all of sudden. Or, say a >>>>> connection comes in every second for say a half an hour. 1800
    connections? Also you need to think about a connection that sends a
    little data then just sits there doing nothing for say 20 minutes.

    You do realise setting up and pulling down a TCP connection takes far more >>>> CPU resources than simply adding a new program counter into the scheduler >>>> list, right?

    You're clearly not an expert on operating systems. There's far
    more involved than "simply adding a new program counter to the scheduler >list"
    during thread creation.

    Actually there isn't that much more but if you think otherwise do fill us in >> on the details.


    Why don't you fill us in on the details? We already know, but you? Humm....

    You made the assertion, you back it up.


    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Scott Lurndal@3:633/10 to All on Mon Jul 6 17:47:00 2026
    Bonita Montero <Bonita.Montero@gmail.com> writes:
    Am 05.07.2026 um 16:41 schrieb Scott Lurndal:


    Process resource limits have been available in Unix since before
    DOS morphed into windows 3.1.

    You can set absolute limits with that, but not fractions of the
    number of cores. Applying the latter is possible since Linux has
    control groups and Windows has no option like that so far.

    You can limit a process to a set of cores, or an individual core
    with taskset and/or numactl. These have been available since the
    early 2000's. Combine that with setrlimit(2) and you have failry
    fined grained control of both core assignment and utilization.


    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Michael S@3:633/10 to All on Mon Jul 6 21:42:17 2026
    On Mon, 6 Jul 2026 09:28:29 -0000 (UTC)
    boltar@caprica.universe wrote:

    On Sun, 5 Jul 2026 13:01:07 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/5/2026 8:48 AM, boltar@caprica.universe wrote:
    A thread pool, I have no idea what your ralloc code is supposed to
    do and I couldn't care less about it. You were claiming thread
    pools are easy to implement so lets see a nice easy example.


    A thread pool in 20 lines? You mean to init the sucker and use it as
    the user right? Not the guts, its going to take more than that. The
    logic is straightforward to me. Yeah, its not that hard because I
    have made so many of them in the past.

    Oh right, so not quite as simple as:

    thread mythread(....)
    mythread.detach()

    then as you were claiming. Glad we finally cleared that up.



    On Windows? Yes, exactly as simple as yours:
    QueueUserWorkItem(mythreadProc, myThreadContext, WT_EXECUTEDEFAULT);

    That is, it is simple for as long as you don't want to join. Otherwise,
    it become more involved. But situations in which join is not necessary
    are common.


    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Michael S@3:633/10 to All on Mon Jul 6 21:49:32 2026
    On Mon, 06 Jul 2026 17:47:00 GMT
    scott@slp53.sl.home (Scott Lurndal) wrote:

    Bonita Montero <Bonita.Montero@gmail.com> writes:
    Am 05.07.2026 um 16:41 schrieb Scott Lurndal:


    Process resource limits have been available in Unix since before
    DOS morphed into windows 3.1.

    You can set absolute limits with that, but not fractions of the
    number of cores. Applying the latter is possible since Linux has
    control groups and Windows has no option like that so far.

    You can limit a process to a set of cores, or an individual core
    with taskset and/or numactl. These have been available since the
    early 2000's.

    That's what Bonita said. Granularity of whole logical core is available
    since long ago.
    But then, on WinNT such granularity is available since very first
    version (1993).
    What Windows (and supposedly POSIX Standard, but not some of POSIX-based systems) lack is finer granularity.

    Combine that with setrlimit(2) and you have failry
    fined grained control of both core assignment and utilization.



    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Chris M. Thomasson@3:633/10 to All on Mon Jul 6 12:31:41 2026
    On 7/6/2026 2:29 AM, boltar@caprica.universe wrote:
    On Sun, 5 Jul 2026 13:22:07 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/3/2026 8:59 AM, boltar@caprica.universe wrote:
    On Fri, 03 Jul 2026 14:41:29 GMT
    scott@slp53.sl.home (Scott Lurndal) gabbled:
    boltar@caprica.universe writes:
    On Thu, 2 Jul 2026 11:41:48 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:

    Thread per connection model? If that works for your work load, so >>>>>> be it.
    Just don't be alarmed if you get 10000 threads all of sudden. Or, >>>>>> say a
    connection comes in every second for say a half an hour. 1800
    connections? Also you need to think about a connection that sends a >>>>>> little data then just sits there doing nothing for say 20 minutes.

    You do realise setting up and pulling down a TCP connection takes
    far more
    CPU resources than simply adding a new program counter into the
    scheduler
    list, right?

    You're clearly not an expert on operating systems.ÿ There's far
    more involved than "simply adding a new program counter to the
    scheduler
    list"
    during thread creation.

    Actually there isn't that much more but if you think otherwise do
    fill us in
    on the details.


    Why don't you fill us in on the details? We already know, but you?
    Humm....

    You made the assertion, you back it up.


    Huh? You made the false assertion! You back it up. We already know. Take
    a look at:

    https://github.com/ZoloZiak/WinNT4

    ;^D



    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Chris M. Thomasson@3:633/10 to All on Mon Jul 6 12:45:40 2026
    On 7/6/2026 11:42 AM, Michael S wrote:
    On Mon, 6 Jul 2026 09:28:29 -0000 (UTC)
    boltar@caprica.universe wrote:

    On Sun, 5 Jul 2026 13:01:07 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/5/2026 8:48 AM, boltar@caprica.universe wrote:
    A thread pool, I have no idea what your ralloc code is supposed to
    do and I couldn't care less about it. You were claiming thread
    pools are easy to implement so lets see a nice easy example.


    A thread pool in 20 lines? You mean to init the sucker and use it as
    the user right? Not the guts, its going to take more than that. The
    logic is straightforward to me. Yeah, its not that hard because I
    have made so many of them in the past.

    Oh right, so not quite as simple as:

    thread mythread(....)
    mythread.detach()

    then as you were claiming. Glad we finally cleared that up.



    On Windows? Yes, exactly as simple as yours:
    QueueUserWorkItem(mythreadProc, myThreadContext, WT_EXECUTEDEFAULT);

    That is, it is simple for as long as you don't want to join. Otherwise,
    it become more involved. But situations in which join is not necessary
    are common.


    Using join for a thread pool can be worked out with proper logic.
    Detached threads, well, imvvvho, are bad mojo anyway, they have their
    place, but I tend to always try to avoid them. Adding threads and
    removing them can use join and a read write mutex for the io_workers in
    the pool. Adding threads and removing them should be very infrequent
    anyway! :^) Usually, we setup a thread pool for say the io_workers that
    are one to one with processing units. We can also oversubscribe with
    creating two threads per. Once that pool is setup, it remains rather
    static.

    Beware of detached threads unless you know what you are doing!



    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Chris M. Thomasson@3:633/10 to All on Mon Jul 6 12:49:24 2026
    On 7/6/2026 2:29 AM, boltar@caprica.universe wrote:
    On Sun, 5 Jul 2026 13:16:11 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/5/2026 8:48 AM, boltar@caprica.universe wrote:
    A thread pool, I have no idea what your ralloc code is supposed to do
    and I
    couldn't care less about it. You were claiming thread pools are easy
    to implement so lets see a nice easy example.


    Also... If you think that over 20 lines is complicated, well... You
    would be fired on the spot?

    You were claiming thread pools are so simple to implement why would anyone not use them. So lets see this simple code of yours, not just some class framework without the details.


    I am going to make one for my iocp memory experiment. There are many
    different ways to engineer them. Then I need to see if I want to use C++ per_thread data, or use C. Actually, using C for TLS is more to the point.

    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Chris M. Thomasson@3:633/10 to All on Mon Jul 6 12:53:36 2026
    On 7/6/2026 12:45 PM, Chris M. Thomasson wrote:
    On 7/6/2026 11:42 AM, Michael S wrote:
    On Mon, 6 Jul 2026 09:28:29 -0000 (UTC)
    boltar@caprica.universe wrote:

    On Sun, 5 Jul 2026 13:01:07 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/5/2026 8:48 AM, boltar@caprica.universe wrote:
    A thread pool, I have no idea what your ralloc code is supposed to
    do and I couldn't care less about it. You were claiming thread
    pools are easy to implement so lets see a nice easy example.

    A thread pool in 20 lines? You mean to init the sucker and use it as
    the user right? Not the guts, its going to take more than that. The
    logic is straightforward to me. Yeah, its not that hard because I
    have made so many of them in the past.

    Oh right, so not quite as simple as:

    thread mythread(....)
    mythread.detach()

    then as you were claiming. Glad we finally cleared that up.



    On Windows? Yes, exactly as simple as yours:
    ÿÿ QueueUserWorkItem(mythreadProc, myThreadContext, WT_EXECUTEDEFAULT);

    That is, it is simple for as long as you don't want to join. Otherwise,
    it become more involved. But situations in which join is not necessary
    are common.


    Using join for a thread pool can be worked out with proper logic.
    Detached threads, well, imvvvho, are bad mojo anyway, they have their
    place, but I tend to always try to avoid them. Adding threads and
    removing them can use join and a read write mutex for the io_workers in
    the pool. Adding threads and removing them should be very infrequent
    anyway! :^) Usually, we setup a thread pool for say the io_workers that
    are one to one with processing units. We can also oversubscribe with creating two threads per. Once that pool is setup, it remains rather
    static.

    Beware of detached threads unless you know what you are doing!



    Iirc in the past, QueueUserWorkItem etc, was not all that performant wrt custom ones. I think windows has a newer one:

    https://learn.microsoft.com/en-us/windows/win32/api/threadpoolapiset/nf-threadpoolapiset-createthreadpool

    https://learn.microsoft.com/en-us/windows/win32/procthread/using-the-thread-pool-functions

    But, I have no problem with making one for myself that only has what it
    needs.


    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From boltar@3:633/10 to All on Tue Jul 7 10:40:28 2026
    On Mon, 6 Jul 2026 21:42:17 +0300
    Michael S <already5chosen@yahoo.com> gabbled:
    On Mon, 6 Jul 2026 09:28:29 -0000 (UTC)
    boltar@caprica.universe wrote:

    On Sun, 5 Jul 2026 13:01:07 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/5/2026 8:48 AM, boltar@caprica.universe wrote:
    A thread pool, I have no idea what your ralloc code is supposed to
    do and I couldn't care less about it. You were claiming thread
    pools are easy to implement so lets see a nice easy example.


    A thread pool in 20 lines? You mean to init the sucker and use it as
    the user right? Not the guts, its going to take more than that. The
    logic is straightforward to me. Yeah, its not that hard because I
    have made so many of them in the past.

    Oh right, so not quite as simple as:

    thread mythread(....)
    mythread.detach()

    then as you were claiming. Glad we finally cleared that up.



    On Windows? Yes, exactly as simple as yours:
    QueueUserWorkItem(mythreadProc, myThreadContext, WT_EXECUTEDEFAULT);

    That is, it is simple for as long as you don't want to join. Otherwise,
    it become more involved. But situations in which join is not necessary
    are common.

    Looks like windows maintains its own thread pool for a user which seems wasteful but understandable in an OS that seems to require threads for everything. *nix however does not. So, i'll ask again for some example thread pool code.


    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From boltar@3:633/10 to All on Tue Jul 7 10:41:03 2026
    On Mon, 6 Jul 2026 12:31:41 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/6/2026 2:29 AM, boltar@caprica.universe wrote:
    On Sun, 5 Jul 2026 13:22:07 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/3/2026 8:59 AM, boltar@caprica.universe wrote:
    On Fri, 03 Jul 2026 14:41:29 GMT
    scott@slp53.sl.home (Scott Lurndal) gabbled:
    boltar@caprica.universe writes:
    On Thu, 2 Jul 2026 11:41:48 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:

    Thread per connection model? If that works for your work load, so >>>>>>> be it.
    Just don't be alarmed if you get 10000 threads all of sudden. Or, >>>>>>> say a
    connection comes in every second for say a half an hour. 1800
    connections? Also you need to think about a connection that sends a >>>>>>> little data then just sits there doing nothing for say 20 minutes. >>>>>>
    You do realise setting up and pulling down a TCP connection takes >>>>>> far more
    CPU resources than simply adding a new program counter into the
    scheduler
    list, right?

    You're clearly not an expert on operating systems.ÿ There's far
    more involved than "simply adding a new program counter to the
    scheduler
    list"
    during thread creation.

    Actually there isn't that much more but if you think otherwise do
    fill us in
    on the details.


    Why don't you fill us in on the details? We already know, but you?
    Humm....

    You made the assertion, you back it up.


    Huh? You made the false assertion! You back it up. We already know. Take
    a look at:

    https://github.com/ZoloZiak/WinNT4

    https://github.com/torvalds/linux

    Enjoy.


    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From boltar@3:633/10 to All on Tue Jul 7 10:41:46 2026
    On Mon, 6 Jul 2026 12:49:24 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/6/2026 2:29 AM, boltar@caprica.universe wrote:
    On Sun, 5 Jul 2026 13:16:11 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/5/2026 8:48 AM, boltar@caprica.universe wrote:
    A thread pool, I have no idea what your ralloc code is supposed to do >>>> and I
    couldn't care less about it. You were claiming thread pools are easy
    to implement so lets see a nice easy example.


    Also... If you think that over 20 lines is complicated, well... You
    would be fired on the spot?

    You were claiming thread pools are so simple to implement why would anyone >> not use them. So lets see this simple code of yours, not just some class
    framework without the details.


    I am going to make one for my iocp memory experiment. There are many >different ways to engineer them. Then I need to see if I want to use C++ >per_thread data, or use C. Actually, using C for TLS is more to the point.

    So you don't have any code yet. Got it.


    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Michael S@3:633/10 to All on Tue Jul 7 20:36:11 2026
    On Tue, 7 Jul 2026 10:40:28 -0000 (UTC)
    boltar@caprica.universe wrote:

    On Mon, 6 Jul 2026 21:42:17 +0300
    Michael S <already5chosen@yahoo.com> gabbled:
    On Mon, 6 Jul 2026 09:28:29 -0000 (UTC)
    boltar@caprica.universe wrote:

    On Sun, 5 Jul 2026 13:01:07 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/5/2026 8:48 AM, boltar@caprica.universe wrote:
    A thread pool, I have no idea what your ralloc code is supposed
    to do and I couldn't care less about it. You were claiming
    thread pools are easy to implement so lets see a nice easy
    example.

    A thread pool in 20 lines? You mean to init the sucker and use it
    as the user right? Not the guts, its going to take more than
    that. The logic is straightforward to me. Yeah, its not that hard
    because I have made so many of them in the past.

    Oh right, so not quite as simple as:

    thread mythread(....)
    mythread.detach()

    then as you were claiming. Glad we finally cleared that up.



    On Windows? Yes, exactly as simple as yours:
    QueueUserWorkItem(mythreadProc, myThreadContext,
    WT_EXECUTEDEFAULT);

    That is, it is simple for as long as you don't want to join.
    Otherwise, it become more involved. But situations in which join is
    not necessary are common.

    Looks like windows maintains its own thread pool for a user which
    seems wasteful

    Why wasteful?
    If you don't use it, it costs you nothing.

    but understandable in an OS that seems to require
    threads for everything. *nix however does not.

    I don't understand what you mean.
    IMHO, portable *nix is the one that needs threads (or fork) for
    everything.
    On Windows, at least in theory, only I/O management (i.e. file open,
    rename, delete etc...) has to be synchronous. For I/O data operations
    (read, write, ioctl) programmer has a choice of whether to do it
    synchronously or asynchronously. The only exception I am aware of are
    anonymous pipes.

    Of course, nowadays file I/O is heavily cached, so even operations
    done through asynchronous APIs behave as synchronous most of the time.
    But that applies to all OSes.

    So, i'll ask again for
    some example thread pool code.




    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Scott Lurndal@3:633/10 to All on Tue Jul 7 18:09:31 2026
    Michael S <already5chosen@yahoo.com> writes:
    On Tue, 7 Jul 2026 10:40:28 -0000 (UTC)
    boltar@caprica.universe wrote:

    On Mon, 6 Jul 2026 21:42:17 +0300
    Michael S <already5chosen@yahoo.com> gabbled:
    On Mon, 6 Jul 2026 09:28:29 -0000 (UTC)
    boltar@caprica.universe wrote:

    On Sun, 5 Jul 2026 13:01:07 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/5/2026 8:48 AM, boltar@caprica.universe wrote:
    A thread pool, I have no idea what your ralloc code is supposed
    to do and I couldn't care less about it. You were claiming
    thread pools are easy to implement so lets see a nice easy
    example.

    A thread pool in 20 lines? You mean to init the sucker and use it
    as the user right? Not the guts, its going to take more than
    that. The logic is straightforward to me. Yeah, its not that hard
    because I have made so many of them in the past.

    Oh right, so not quite as simple as:

    thread mythread(....)
    mythread.detach()

    then as you were claiming. Glad we finally cleared that up.



    On Windows? Yes, exactly as simple as yours:
    QueueUserWorkItem(mythreadProc, myThreadContext,
    WT_EXECUTEDEFAULT);

    That is, it is simple for as long as you don't want to join.
    Otherwise, it become more involved. But situations in which join is
    not necessary are common.

    Looks like windows maintains its own thread pool for a user which
    seems wasteful

    Why wasteful?
    If you don't use it, it costs you nothing.

    but understandable in an OS that seems to require
    threads for everything. *nix however does not.

    I don't understand what you mean.
    IMHO, portable *nix is the one that needs threads (or fork) for
    everything.
    On Windows, at least in theory, only I/O management (i.e. file open,
    rename, delete etc...) has to be synchronous. For I/O data operations
    (read, write, ioctl) programmer has a choice of whether to do it >synchronously or asynchronously. The only exception I am aware of are >anonymous pipes.

    Of course, nowadays file I/O is heavily cached, so even operations
    done through asynchronous APIs behave as synchronous most of the time.
    But that applies to all OSes.

    Does windows have the equivalent of unix raw devices or linux O_DIRECT,
    both of which avoid the buffer or file caches in the OS (and the user level stdio caching)?


    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Michael S@3:633/10 to All on Tue Jul 7 21:40:32 2026
    On Tue, 07 Jul 2026 18:09:31 GMT
    scott@slp53.sl.home (Scott Lurndal) wrote:

    Michael S <already5chosen@yahoo.com> writes:
    On Tue, 7 Jul 2026 10:40:28 -0000 (UTC)
    boltar@caprica.universe wrote:

    On Mon, 6 Jul 2026 21:42:17 +0300
    Michael S <already5chosen@yahoo.com> gabbled:
    On Mon, 6 Jul 2026 09:28:29 -0000 (UTC)
    boltar@caprica.universe wrote:

    On Sun, 5 Jul 2026 13:01:07 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:

    On 7/5/2026 8:48 AM, boltar@caprica.universe wrote:
    A thread pool, I have no idea what your ralloc code is
    supposed to do and I couldn't care less about it. You were
    claiming thread pools are easy to implement so lets see a
    nice easy example.

    A thread pool in 20 lines? You mean to init the sucker and use
    it as the user right? Not the guts, its going to take more than
    that. The logic is straightforward to me. Yeah, its not that
    hard because I have made so many of them in the past.

    Oh right, so not quite as simple as:

    thread mythread(....)
    mythread.detach()

    then as you were claiming. Glad we finally cleared that up.



    On Windows? Yes, exactly as simple as yours:
    QueueUserWorkItem(mythreadProc, myThreadContext,
    WT_EXECUTEDEFAULT);

    That is, it is simple for as long as you don't want to join.
    Otherwise, it become more involved. But situations in which join
    is not necessary are common.

    Looks like windows maintains its own thread pool for a user which
    seems wasteful

    Why wasteful?
    If you don't use it, it costs you nothing.

    but understandable in an OS that seems to require
    threads for everything. *nix however does not.

    I don't understand what you mean.
    IMHO, portable *nix is the one that needs threads (or fork) for
    everything.
    On Windows, at least in theory, only I/O management (i.e. file open, >rename, delete etc...) has to be synchronous. For I/O data operations >(read, write, ioctl) programmer has a choice of whether to do it >synchronously or asynchronously. The only exception I am aware of are >anonymous pipes.

    Of course, nowadays file I/O is heavily cached, so even operations
    done through asynchronous APIs behave as synchronous most of the
    time. But that applies to all OSes.

    Does windows have the equivalent of unix raw devices or linux
    O_DIRECT, both of which avoid the buffer or file caches in the OS
    (and the user level stdio caching)?


    I was never interested in raw devices, so don't know.
    Surely, even if support is here it would require admin privilege.

    As to O_DIRECT, one can open file with FILE_FLAG_NO_BUFFERING flag.
    But when you do it then there are serious restriction on what allowed
    and what not. https://learn.microsoft.com/en-us/windows/win32/fileio/file-buffering
    Again, I never was interested.









    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Chris M. Thomasson@3:633/10 to All on Tue Jul 7 15:07:43 2026
    On 7/6/2026 12:53 PM, Chris M. Thomasson wrote:
    On 7/6/2026 12:45 PM, Chris M. Thomasson wrote:
    On 7/6/2026 11:42 AM, Michael S wrote:
    On Mon, 6 Jul 2026 09:28:29 -0000 (UTC)
    boltar@caprica.universe wrote:

    On Sun, 5 Jul 2026 13:01:07 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/5/2026 8:48 AM, boltar@caprica.universe wrote:
    A thread pool, I have no idea what your ralloc code is supposed to >>>>>> do and I couldn't care less about it. You were claiming thread
    pools are easy to implement so lets see a nice easy example.

    A thread pool in 20 lines? You mean to init the sucker and use it as >>>>> the user right? Not the guts, its going to take more than that. The
    logic is straightforward to me. Yeah, its not that hard because I
    have made so many of them in the past.

    Oh right, so not quite as simple as:

    thread mythread(....)
    mythread.detach()

    then as you were claiming. Glad we finally cleared that up.



    On Windows? Yes, exactly as simple as yours:
    ÿÿ QueueUserWorkItem(mythreadProc, myThreadContext, WT_EXECUTEDEFAULT);

    That is, it is simple for as long as you don't want to join. Otherwise,
    it become more involved. But situations in which join is not necessary
    are common.


    Using join for a thread pool can be worked out with proper logic.
    Detached threads, well, imvvvho, are bad mojo anyway, they have their
    place, but I tend to always try to avoid them. Adding threads and
    removing them can use join and a read write mutex for the io_workers
    in the pool. Adding threads and removing them should be very
    infrequent anyway! :^) Usually, we setup a thread pool for say the
    io_workers that are one to one with processing units. We can also
    oversubscribe with creating two threads per. Once that pool is setup,
    it remains rather static.

    Beware of detached threads unless you know what you are doing!



    Iirc in the past, QueueUserWorkItem etc, was not all that performant wrt custom ones. I think windows has a newer one:

    https://learn.microsoft.com/en-us/windows/win32/api/threadpoolapiset/nf- threadpoolapiset-createthreadpool

    https://learn.microsoft.com/en-us/windows/win32/procthread/using-the- thread-pool-functions

    But, I have no problem with making one for myself that only has what it needs.


    I need to take a look. I don't know if they work with IOCP in the way I
    need. Anyway, I remember a special logic I used for my io_worker threads
    that might be incompatible with the "new" windows thread pool. It worked
    with per_thread cohorts and was able to fill them up using per_io
    completions. If a cohort got too full, it would be processed. Or if a
    gqcsex failed to return any per_io's with a zero timeout, they would be processed. akin to:

    for (;;)
    {
    if (! gqcsex(..., 0)) // 0 timeout
    {
    process_cohort();

    gqcxex(..., INFINITE); // wait
    }

    push_to_cohort(...);

    if (cohort.size() > cohort_threshold)
    {
    process_cohort();
    }
    }

    Each cohort was only able to be seen by its io_worker.


    push_to_cohort would just link the completed per_io's to their correct
    list using its bitmask flags, example:

    struct cohort
    {
    cohort* m_next;
    size_t m_size;

    per_io* m_recv;
    per_io* m_send;
    per_io* m_accept;
    per_io* m_connect;
    per_io* m_file_read;
    per_io* m_file_write;

    // etc...
    };


    So, when a cohort gets processed it just walks itself. The good part is
    that it has damn good cache locality. Processing all of the recvs in a
    batch is good.

    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Scott Lurndal@3:633/10 to All on Tue Jul 7 22:11:48 2026
    Michael S <already5chosen@yahoo.com> writes:
    On Tue, 07 Jul 2026 18:09:31 GMT
    scott@slp53.sl.home (Scott Lurndal) wrote:


    Does windows have the equivalent of unix raw devices or linux
    O_DIRECT, both of which avoid the buffer or file caches in the OS
    (and the user level stdio caching)?


    I was never interested in raw devices, so don't know.
    Surely, even if support is here it would require admin privilege.

    As to O_DIRECT, one can open file with FILE_FLAG_NO_BUFFERING flag.
    But when you do it then there are serious restriction on what allowed
    and what not.

    Makes sense - direct I/O accesses need to be sector-aligned, same
    as unix raw devices.

    Useful for filesystem maintenance utilities and high-end databases.

    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Chris M. Thomasson@3:633/10 to All on Tue Jul 7 15:17:01 2026
    On 7/7/2026 3:41 AM, boltar@caprica.universe wrote:
    On Mon, 6 Jul 2026 12:49:24 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/6/2026 2:29 AM, boltar@caprica.universe wrote:
    On Sun, 5 Jul 2026 13:16:11 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/5/2026 8:48 AM, boltar@caprica.universe wrote:
    A thread pool, I have no idea what your ralloc code is supposed to
    do and I
    couldn't care less about it. You were claiming thread pools are
    easy to implement so lets see a nice easy example.


    Also... If you think that over 20 lines is complicated, well... You
    would be fired on the spot?

    You were claiming thread pools are so simple to implement why would
    anyone
    not use them. So lets see this simple code of yours, not just some class >>> framework without the details.


    I am going to make one for my iocp memory experiment. There are many
    different ways to engineer them. Then I need to see if I want to use
    C++ per_thread data, or use C. Actually, using C for TLS is more to
    the point.

    So you don't have any code yet. Got it.


    You are too funny. wow. I think have posted a specialized one for a
    lock-free stack test here a couple of months ago. But, trust me. I know
    how to make them in many different forms. You think I am going to spend
    my free time on your difficultly? When I get around to making my iocp
    thread pool, I will show you, but you will just mock it out of ignorance
    or something. Sigh.

    Oh, well, this is a specialized one I posted for an experimental futex
    based lock-free stack:



    My code:
    ______________________________________
    #include <iostream>
    #include <thread>
    #include <atomic>
    #include <algorithm>
    #include <cassert>


    #define CT_THREAD_N (42)
    #define CT_WORK_N (10000000)
    #define CT_WAIT ((ct_node*)0xDEADBEEF)


    struct ct_node
    {
    ct_node* m_next = { nullptr };

    ct_node()
    {
    //std::cout << "(" << this << ")::ct_node::ct_node()\n";
    }

    ~ct_node()
    {
    //std::cout << "(" << this << ")::ct_node::~ct_node()\n";
    }
    };


    struct ct_stack
    {
    std::atomic<ct_node*> m_head = { nullptr };

    void
    push(
    ct_node* node
    ) {
    ct_node* head = m_head.load(std::memory_order_relaxed);

    do
    {
    if (head == CT_WAIT)
    {
    node->m_next = nullptr;
    }

    else
    {
    node->m_next = head;
    }

    } while (! m_head.compare_exchange_weak(
    head,
    node,
    std::memory_order_release)
    );

    if (head == CT_WAIT)
    {
    // slow path...
    m_head.notify_one();
    }
    }

    ct_node*
    flush_wait()
    {
    ct_node* head = nullptr;

    for (;;)
    {
    head = m_head.exchange(nullptr, std::memory_order_acquire);

    while (! head || head == CT_WAIT)
    {
    // slow path...
    head = m_head.exchange(CT_WAIT, std::memory_order_acquire);

    if (! head || head == CT_WAIT)
    {
    m_head.wait(CT_WAIT, std::memory_order_relaxed);
    continue;
    }
    }

    break;
    }

    assert(head && head != CT_WAIT);

    return head;
    }
    };


    struct ct_work : public ct_node
    {
    unsigned long m_state = { 0 };
    };


    struct ct_shared
    {
    ct_stack m_stack_in;
    ct_stack m_stack_out;

    ct_shared()
    {
    std::cout << "ct_shared::ct_shared()\n" << std::endl;
    }

    ~ct_shared()
    {
    assert(! m_stack_in.m_head || m_stack_in.m_head == CT_WAIT);
    assert(! m_stack_out.m_head || m_stack_out.m_head == CT_WAIT);

    std::cout << "ct_shared::~ct_shared()\n" << std::endl;
    }
    };


    void
    ct_thread(
    ct_shared& shared
    ) {
    unsigned long state = 0;

    while (! state)
    {
    ct_work* head = (ct_work*)shared.m_stack_in.flush_wait();

    while (head)
    {
    ct_work* next = (ct_work*)head->m_next;

    if (head->m_state == 666)
    {
    // Shutdown detected...
    state = 1;
    shared.m_stack_in.push(head);
    }

    else
    {
    shared.m_stack_out.push(head);
    }

    head = next;
    }
    }

    //std::cout << "shutdown..." << std::endl;
    }


    int
    main()
    {
    {
    std::cout << "Futex Stack Test\n";
    std::cout << "by: Chris M. Thomasson\n";
    std::cout << "version: (0.0.1)\n";
    std::cout << "_________________________________\n" << std::endl;
    }

    unsigned long g_ct_work_alloations = 0;
    unsigned long g_ct_work_dealloations = 0;

    {
    std::cout << "CT_THREAD_N = " << CT_THREAD_N << std::endl;
    std::cout << "CT_WORK_N = " << CT_WORK_N << std::endl;
    std::cout << "CT_WAIT = " << CT_WAIT << std::endl;
    }

    {
    ct_shared shared = { };

    std::thread threads[CT_THREAD_N];

    std::cout << "\nLaunching threads...\n" << std::endl;

    for (unsigned long i = 0; i < CT_THREAD_N; ++i)
    {
    threads[i] = std::thread(ct_thread, std::ref(shared));
    }

    //std::this_thread::sleep_for(std::chrono::seconds(2));

    std::cout << "\nGenerate work...\n" << std::endl;

    // Generate work...
    {
    for (unsigned long i = 0; i < CT_WORK_N; ++i)
    {
    shared.m_stack_in.push(new ct_work);
    ++g_ct_work_alloations;
    }
    }

    // Wait for work...
    {
    unsigned long wn = 0;

    while (wn < CT_WORK_N)
    {
    ct_work* head = (ct_work*)shared.m_stack_out.flush_wait();

    while (head)
    {
    ct_work* next = (ct_work*)head->m_next;
    delete head;
    ++g_ct_work_dealloations;
    ++wn;
    head = next;
    }
    }
    }

    std::cout << "\nCompleted all work!\n" << std::endl;
    std::cout << "Sending shutdown state...\n" << std::endl;

    // Send shutdown state...
    {
    for (unsigned long i = 0; i < CT_THREAD_N; ++i)
    {
    ct_work* w = new ct_work;
    ++g_ct_work_alloations;
    w->m_state = 666;
    shared.m_stack_in.push(w);
    }
    }

    // Join threads...
    {
    for (unsigned long i = 0; i < CT_THREAD_N; ++i)
    {
    threads[i].join();
    }
    }

    std::cout << "\nThreads joined...\n" << std::endl;

    // Dump shutdown state...
    std::cout << "Dump shutdown state...\n" << std::endl;

    {
    ct_work* head = (ct_work*)shared.m_stack_in.m_head.load(std::memory_order_relaxed);
    shared.m_stack_in.m_head = nullptr;

    while (head)
    {
    ct_work* next = (ct_work*)head->m_next;
    delete head;
    ++g_ct_work_dealloations;
    head = next;
    }
    }

    std::cout << "\nShutdown complete!\n" << std::endl;
    }

    // Sanity check...
    {
    std::cout << "g_ct_work_alloations = " << g_ct_work_alloations
    << "\n";
    std::cout << "g_ct_work_dealloations = " <<
    g_ct_work_dealloations << std::endl;

    if (g_ct_work_alloations != g_ct_work_dealloations)
    {
    std::cout << "Pardon my French, but shit!!!!!!!!!!!!!! NOT GOOD\n" << std::endl;
    std::cout << "DAMN IT!!!! Grrrrr\n" << std::endl;
    }
    }

    std::cout << "\nFin!\n" << std::endl;

    return 0;
    }
    ______________________________________




    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Chris M. Thomasson@3:633/10 to All on Tue Jul 7 15:19:19 2026
    On 7/7/2026 3:41 AM, boltar@caprica.universe wrote:
    On Mon, 6 Jul 2026 12:49:24 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/6/2026 2:29 AM, boltar@caprica.universe wrote:
    On Sun, 5 Jul 2026 13:16:11 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/5/2026 8:48 AM, boltar@caprica.universe wrote:
    A thread pool, I have no idea what your ralloc code is supposed to
    do and I
    couldn't care less about it. You were claiming thread pools are
    easy to implement so lets see a nice easy example.


    Also... If you think that over 20 lines is complicated, well... You
    would be fired on the spot?

    You were claiming thread pools are so simple to implement why would
    anyone
    not use them. So lets see this simple code of yours, not just some class >>> framework without the details.


    I am going to make one for my iocp memory experiment. There are many
    different ways to engineer them. Then I need to see if I want to use
    C++ per_thread data, or use C. Actually, using C for TLS is more to
    the point.

    So you don't have any code yet. Got it.


    Take a look at an older post of mine from 2025:

    Futex Stack Test...

    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Chris M. Thomasson@3:633/10 to All on Tue Jul 7 15:30:29 2026
    On 7/7/2026 3:41 AM, boltar@caprica.universe wrote:
    On Mon, 6 Jul 2026 12:31:41 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/6/2026 2:29 AM, boltar@caprica.universe wrote:
    On Sun, 5 Jul 2026 13:22:07 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/3/2026 8:59 AM, boltar@caprica.universe wrote:
    On Fri, 03 Jul 2026 14:41:29 GMT
    scott@slp53.sl.home (Scott Lurndal) gabbled:
    boltar@caprica.universe writes:
    On Thu, 2 Jul 2026 11:41:48 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:

    Thread per connection model? If that works for your work load, >>>>>>>> so be it.
    Just don't be alarmed if you get 10000 threads all of sudden. >>>>>>>> Or, say a
    connection comes in every second for say a half an hour. 1800
    connections? Also you need to think about a connection that sends a >>>>>>>> little data then just sits there doing nothing for say 20 minutes. >>>>>>>
    You do realise setting up and pulling down a TCP connection takes >>>>>>> far more
    CPU resources than
    list, right?

    You're clearly not an expert on operating systems.ÿ There's far
    more involved than "simply adding a new program counter to the
    scheduler
    list"
    during thread creation.

    Actually there isn't that much more but if you think otherwise do
    fill us in
    on the details.


    Why don't you fill us in on the details? We already know, but you?
    Humm....

    You made the assertion, you back it up.


    Huh? You made the false assertion! You back it up. We already know.
    Take a look at:

    https://github.com/ZoloZiak/WinNT4

    https://github.com/torvalds/linux

    Enjoy.


    You made an assertion that creating a new thread "is simply adding a new program counter into the scheduler". I have a feeling that you don't
    know what you are talking about. Scott tried to tell you that you are wrong.

    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From boltar@3:633/10 to All on Wed Jul 8 09:34:40 2026
    On Tue, 7 Jul 2026 20:36:11 +0300
    Michael S <already5chosen@yahoo.com> gabbled:
    On Tue, 7 Jul 2026 10:40:28 -0000 (UTC)
    boltar@caprica.universe wrote:
    Looks like windows maintains its own thread pool for a user which
    seems wasteful

    Why wasteful?
    If you don't use it, it costs you nothing.

    It costs the kernel time and resources or do you think its all done by
    magic pixies?

    but understandable in an OS that seems to require
    threads for everything. *nix however does not.

    I don't understand what you mean.
    IMHO, portable *nix is the one that needs threads (or fork) for
    everything.

    Wtf are you talking about? Its quite possible - and I've done it a number of times - to write a network server in unix with a single thread & single process using multiplexed sockets via select() or poll(). Thats how 1990s MUD & chat servers were written and IRC, Unaxcess along with plenty of other in house company servers.


    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From boltar@3:633/10 to All on Wed Jul 8 09:38:00 2026
    On Tue, 7 Jul 2026 15:17:01 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/7/2026 3:41 AM, boltar@caprica.universe wrote:
    On Mon, 6 Jul 2026 12:49:24 -0700
    So you don't have any code yet. Got it.


    You are too funny. wow. I think have posted a specialized one for a >lock-free stack test here a couple of months ago. But, trust me. I know
    how to make them in many different forms. You think I am going to spend

    So you won't have a problem writing some short example code then will you.

    Oh, well, this is a specialized one I posted for an experimental futex
    based lock-free stack:

    I'm jnot wading through 270 lines of code. Demonstrate how "simple" thread pools are to implement or STFU.


    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From boltar@3:633/10 to All on Wed Jul 8 09:38:52 2026
    On Tue, 7 Jul 2026 15:30:29 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/7/2026 3:41 AM, boltar@caprica.universe wrote:
    On Mon, 6 Jul 2026 12:31:41 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/6/2026 2:29 AM, boltar@caprica.universe wrote:
    On Sun, 5 Jul 2026 13:22:07 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/3/2026 8:59 AM, boltar@caprica.universe wrote:
    On Fri, 03 Jul 2026 14:41:29 GMT
    scott@slp53.sl.home (Scott Lurndal) gabbled:
    boltar@caprica.universe writes:
    On Thu, 2 Jul 2026 11:41:48 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:

    Thread per connection model? If that works for your work load, >>>>>>>>> so be it.
    Just don't be alarmed if you get 10000 threads all of sudden. >>>>>>>>> Or, say a
    connection comes in every second for say a half an hour. 1800 >>>>>>>>> connections? Also you need to think about a connection that sends a >>>>>>>>> little data then just sits there doing nothing for say 20 minutes. >>>>>>>>
    You do realise setting up and pulling down a TCP connection takes >>>>>>>> far more
    CPU resources than
    list, right?

    You're clearly not an expert on operating systems.ÿ There's far
    more involved than "simply adding a new program counter to the
    scheduler
    list"
    during thread creation.

    Actually there isn't that much more but if you think otherwise do >>>>>> fill us in
    on the details.


    Why don't you fill us in on the details? We already know, but you?
    Humm....

    You made the assertion, you back it up.


    Huh? You made the false assertion! You back it up. We already know.
    Take a look at:

    https://github.com/ZoloZiak/WinNT4

    https://github.com/torvalds/linux

    Enjoy.


    You made an assertion that creating a new thread "is simply adding a new >program counter into the scheduler". I have a feeling that you don't
    know what you are talking about. Scott tried to tell you that you are wrong.

    You simply revered to the NT4 code so I simply refered to the linux code.
    Whats the problem?


    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Bonita Montero@3:633/10 to All on Wed Jul 8 15:47:46 2026
    Am 06.07.2026 um 20:49 schrieb Michael S:

    That's what Bonita said. ....

    No, I'm talking about a limit to the amount of consumed CPU time of
    a thread in an interval. With Linux that's possible since Linux has
    control groups. Windows never had such a capability.

    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Michael S@3:633/10 to All on Wed Jul 8 22:16:55 2026
    On Wed, 8 Jul 2026 09:34:40 -0000 (UTC)
    boltar@caprica.universe wrote:

    On Tue, 7 Jul 2026 20:36:11 +0300
    Michael S <already5chosen@yahoo.com> gabbled:
    On Tue, 7 Jul 2026 10:40:28 -0000 (UTC)
    boltar@caprica.universe wrote:
    Looks like windows maintains its own thread pool for a user which
    seems wasteful

    Why wasteful?
    If you don't use it, it costs you nothing.

    It costs the kernel time and resources or do you think its all done
    by magic pixies?


    It costs only if you use it.
    Otherwise, accordiing to my understanding, the only cost is few zero-initialized fields in process control block.

    but understandable in an OS that seems to require
    threads for everything. *nix however does not.

    I don't understand what you mean.
    IMHO, portable *nix is the one that needs threads (or fork) for
    everything.

    Wtf are you talking about?

    I am talking about file IO. Was not it obvious?

    Its quite possible - and I've done it a
    number of times - to write a network server in unix with a single
    thread & single process using multiplexed sockets via select() or
    poll().

    Then either files access in your server was blocking or you used
    non-portable extensions to POSIX.
    And it's not like on Windows it would be different. Except, may be, if
    you want to support very old versions of Windows (>20 y.o.) in
    whichcasee you'll only have select() and no poll(). Which is
    inconvinience, but relatively minor one.

    Thats how 1990s MUD & chat servers were written and IRC,
    Unaxcess along with plenty of other in house company servers.





    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Chris M. Thomasson@3:633/10 to All on Wed Jul 8 14:13:54 2026
    On 7/8/2026 2:38 AM, boltar@caprica.universe wrote:
    On Tue, 7 Jul 2026 15:30:29 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/7/2026 3:41 AM, boltar@caprica.universe wrote:
    On Mon, 6 Jul 2026 12:31:41 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/6/2026 2:29 AM, boltar@caprica.universe wrote:
    On Sun, 5 Jul 2026 13:22:07 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/3/2026 8:59 AM, boltar@caprica.universe wrote:
    On Fri, 03 Jul 2026 14:41:29 GMT
    scott@slp53.sl.home (Scott Lurndal) gabbled:
    boltar@caprica.universe writes:
    On Thu, 2 Jul 2026 11:41:48 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled: >>>>>>>>
    Thread per connection model? If that works for your work load, >>>>>>>>>> so be it.
    Just don't be alarmed if you get 10000 threads all of sudden. >>>>>>>>>> Or, say a
    connection comes in every second for say a half an hour. 1800 >>>>>>>>>> connections? Also you need to think about a connection that >>>>>>>>>> sends a
    little data then just sits there doing nothing for say 20 >>>>>>>>>> minutes.

    You do realise setting up and pulling down a TCP connection >>>>>>>>> takes far more
    CPU resources than list, right?

    You're clearly not an expert on operating systems.ÿ There's far >>>>>>>> more involved than "simply adding a new program counter to the >>>>>>>> scheduler
    list"
    during thread creation.

    Actually there isn't that much more but if you think otherwise do >>>>>>> fill us in
    on the details.


    Why don't you fill us in on the details? We already know, but you? >>>>>> Humm....

    You made the assertion, you back it up.


    Huh? You made the false assertion! You back it up. We already know.
    Take a look at:

    https://github.com/ZoloZiak/WinNT4

    https://github.com/torvalds/linux

    Enjoy.


    You made an assertion that creating a new thread "is simply adding a
    new program counter into the scheduler". I have a feeling that you
    don't know what you are talking about. Scott tried to tell you that
    you are wrong.

    You simply revered to the NT4 code so I simply refered to the linux code. Whats the problem?


    Well, its a lot more than just, like you said: "simply adding a new
    program counter to the scheduler list"

    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Chris M. Thomasson@3:633/10 to All on Wed Jul 8 14:15:20 2026
    On 7/8/2026 2:34 AM, boltar@caprica.universe wrote:
    On Tue, 7 Jul 2026 20:36:11 +0300
    Michael S <already5chosen@yahoo.com> gabbled:
    On Tue, 7 Jul 2026 10:40:28 -0000 (UTC)
    boltar@caprica.universe wrote:
    Looks like windows maintains its own thread pool for a user which
    seems wasteful

    Why wasteful?
    If you don't use it, it costs you nothing.

    It costs the kernel time and resources or do you think its all done by
    magic pixies?

    HUH? If you don't create a thread pool in Windows, you are not using
    one. There is no cost. Sigh...



    but understandable in an OS that seems to require
    threads for everything. *nix however does not.

    I don't understand what you mean.
    IMHO, portable *nix is the one that needs threads (or fork) for
    everything.

    Wtf are you talking about? Its quite possible - and I've done it a number of times - to write a network server in unix with a single thread & single process
    using multiplexed sockets via select() or poll(). Thats how 1990s MUD & chat servers were written and IRC, Unaxcess along with plenty of other in house company servers.



    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Chris M. Thomasson@3:633/10 to All on Wed Jul 8 14:16:33 2026
    On 7/8/2026 12:16 PM, Michael S wrote:
    On Wed, 8 Jul 2026 09:34:40 -0000 (UTC)
    boltar@caprica.universe wrote:

    On Tue, 7 Jul 2026 20:36:11 +0300
    Michael S <already5chosen@yahoo.com> gabbled:
    On Tue, 7 Jul 2026 10:40:28 -0000 (UTC)
    boltar@caprica.universe wrote:
    Looks like windows maintains its own thread pool for a user which
    seems wasteful

    Why wasteful?
    If you don't use it, it costs you nothing.

    It costs the kernel time and resources or do you think its all done
    by magic pixies?


    It costs only if you use it.
    Otherwise, accordiing to my understanding, the only cost is few zero-initialized fields in process control block.

    but understandable in an OS that seems to require
    threads for everything. *nix however does not.

    I don't understand what you mean.
    IMHO, portable *nix is the one that needs threads (or fork) for
    everything.

    Wtf are you talking about?

    I am talking about file IO. Was not it obvious?

    Its quite possible - and I've done it a
    number of times - to write a network server in unix with a single
    thread & single process using multiplexed sockets via select() or
    poll().

    Then either files access in your server was blocking or you used
    non-portable extensions to POSIX.
    And it's not like on Windows it would be different. Except, may be, if
    you want to support very old versions of Windows (>20 y.o.) in
    whichcasee you'll only have select() and no poll(). Which is
    inconvinience, but relatively minor one.

    Winnt 4.0 had IOCP that works with sockets and files.




    Thats how 1990s MUD & chat servers were written and IRC,
    Unaxcess along with plenty of other in house company servers.






    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Chris M. Thomasson@3:633/10 to All on Wed Jul 8 14:17:06 2026
    On 7/8/2026 2:38 AM, boltar@caprica.universe wrote:
    On Tue, 7 Jul 2026 15:17:01 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/7/2026 3:41 AM, boltar@caprica.universe wrote:
    On Mon, 6 Jul 2026 12:49:24 -0700
    So you don't have any code yet. Got it.


    You are too funny. wow. I think have posted a specialized one for a
    lock-free stack test here a couple of months ago. But, trust me. I
    know how to make them in many different forms. You think I am going to
    spend

    So you won't have a problem writing some short example code then will you.

    Oh, well, this is a specialized one I posted for an experimental futex
    based lock-free stack:

    I'm jnot wading through 270 lines of code. Demonstrate how "simple" thread pools are to implement or STFU.


    Huh? Make a thread pool is less than 20 lines? Are you daft?

    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Chris M. Thomasson@3:633/10 to All on Wed Jul 8 14:32:34 2026
    On 7/8/2026 6:47 AM, Bonita Montero wrote:
    Am 06.07.2026 um 20:49 schrieb Michael S:

    That's what Bonita said. ....

    No, I'm talking about a limit to the amount of consumed CPU time of
    a thread in an interval. With Linux that's possible since Linux has
    control groups. Windows never had such a capability.

    Not sure if a processor group can work with the power management or not.
    I think it can.

    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Bonita Montero@3:633/10 to All on Thu Jul 9 10:34:51 2026
    Am 08.07.2026 um 23:32 schrieb Chris M. Thomasson:

    Not sure if a processor group can work with the power management or not.
    I think it can.

    OMG, what a nonsense.

    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From boltar@3:633/10 to All on Thu Jul 9 08:55:22 2026
    On Wed, 8 Jul 2026 22:16:55 +0300
    Michael S <already5chosen@yahoo.com> gabbled:
    On Wed, 8 Jul 2026 09:34:40 -0000 (UTC)
    boltar@caprica.universe wrote:

    On Tue, 7 Jul 2026 20:36:11 +0300
    Michael S <already5chosen@yahoo.com> gabbled:
    On Tue, 7 Jul 2026 10:40:28 -0000 (UTC)
    boltar@caprica.universe wrote:
    Looks like windows maintains its own thread pool for a user which
    seems wasteful

    Why wasteful?
    If you don't use it, it costs you nothing.

    It costs the kernel time and resources or do you think its all done
    by magic pixies?


    It costs only if you use it.
    Otherwise, accordiing to my understanding, the only cost is few >zero-initialized fields in process control block.

    Whooosh....

    I don't understand what you mean.
    IMHO, portable *nix is the one that needs threads (or fork) for
    everything.

    Wtf are you talking about?

    I am talking about file IO. Was not it obvious?

    No it wasn't and no you don't need seperate threads to do file I/O , you
    can simply multiplex the descriptors in select or poll just like sockets.

    Its quite possible - and I've done it a
    number of times - to write a network server in unix with a single
    thread & single process using multiplexed sockets via select() or
    poll().

    Then either files access in your server was blocking or you used
    non-portable extensions to POSIX.

    Clearly you don't understand how multiplexing works in unix but given file
    I/O in userspace is buffered anyway you rarely need to multiplex file I/O unless its via NFS or similar.

    And it's not like on Windows it would be different. Except, may be, if
    you want to support very old versions of Windows (>20 y.o.) in
    whichcasee you'll only have select() and no poll(). Which is
    inconvinience, but relatively minor one.

    select and poll are not an "inconvenience", they're fundamental to how
    single threaded servers are implemented on unix. Don't assume just because
    the windows versions are a pale shadow of the posix ones doesn't mean that they're useless.


    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From boltar@3:633/10 to All on Thu Jul 9 08:55:59 2026
    On Wed, 8 Jul 2026 14:15:20 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/8/2026 2:34 AM, boltar@caprica.universe wrote:
    On Tue, 7 Jul 2026 20:36:11 +0300
    Michael S <already5chosen@yahoo.com> gabbled:
    On Tue, 7 Jul 2026 10:40:28 -0000 (UTC)
    boltar@caprica.universe wrote:
    Looks like windows maintains its own thread pool for a user which
    seems wasteful

    Why wasteful?
    If you don't use it, it costs you nothing.

    It costs the kernel time and resources or do you think its all done by
    magic pixies?

    HUH? If you don't create a thread pool in Windows, you are not using
    one. There is no cost. Sigh...

    And then the pool is created is just appears by magic, no setup required
    on the part of the OS?


    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From boltar@3:633/10 to All on Thu Jul 9 08:56:36 2026
    On Wed, 8 Jul 2026 14:17:06 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/8/2026 2:38 AM, boltar@caprica.universe wrote:
    On Tue, 7 Jul 2026 15:17:01 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/7/2026 3:41 AM, boltar@caprica.universe wrote:
    On Mon, 6 Jul 2026 12:49:24 -0700
    So you don't have any code yet. Got it.


    You are too funny. wow. I think have posted a specialized one for a
    lock-free stack test here a couple of months ago. But, trust me. I
    know how to make them in many different forms. You think I am going to
    spend

    So you won't have a problem writing some short example code then will you. >>
    Oh, well, this is a specialized one I posted for an experimental futex
    based lock-free stack:

    I'm jnot wading through 270 lines of code. Demonstrate how "simple" thread >> pools are to implement or STFU.


    Huh? Make a thread pool is less than 20 lines? Are you daft?

    You were the one claiming how they were so simple to implement. But nice attempt at a back pedal.


    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Scott Lurndal@3:633/10 to All on Thu Jul 9 15:18:38 2026
    boltar@caprica.universe writes:
    On Wed, 8 Jul 2026 22:16:55 +0300
    Michael S <already5chosen@yahoo.com> gabbled:
    On Wed, 8 Jul 2026 09:34:40 -0000 (UTC)
    boltar@caprica.universe wrote:

    On Tue, 7 Jul 2026 20:36:11 +0300
    Michael S <already5chosen@yahoo.com> gabbled:
    On Tue, 7 Jul 2026 10:40:28 -0000 (UTC)
    boltar@caprica.universe wrote:
    Looks like windows maintains its own thread pool for a user which
    seems wasteful

    Why wasteful?
    If you don't use it, it costs you nothing.

    It costs the kernel time and resources or do you think its all done
    by magic pixies?


    It costs only if you use it.
    Otherwise, accordiing to my understanding, the only cost is few >>zero-initialized fields in process control block.

    Whooosh....

    I don't understand what you mean.
    IMHO, portable *nix is the one that needs threads (or fork) for
    everything.

    Wtf are you talking about?

    I am talking about file IO. Was not it obvious?

    No it wasn't and no you don't need seperate threads to do file I/O , you
    can simply multiplex the descriptors in select or poll just like sockets.

    Actually, you can't usefully poll regular files. POLLIN and POLLOUT are always true for
    a regular file.

    aio_read(2), aio_write(2) and lio_listio(2) provide asynchronous
    file I/O.



    Its quite possible - and I've done it a
    number of times - to write a network server in unix with a single
    thread & single process using multiplexed sockets via select() or
    poll().

    Then either files access in your server was blocking or you used >>non-portable extensions to POSIX.

    Clearly you don't understand how multiplexing works in unix but given file >I/O in userspace is buffered anyway you rarely need to multiplex file I/O >unless its via NFS or similar.

    No high performance application will use stdio buffering.

    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From boltar@3:633/10 to All on Thu Jul 9 15:43:19 2026
    On Thu, 09 Jul 2026 15:18:38 GMT
    scott@slp53.sl.home (Scott Lurndal) gabbled:
    boltar@caprica.universe writes:
    No it wasn't and no you don't need seperate threads to do file I/O , you >>can simply multiplex the descriptors in select or poll just like sockets.

    Actually, you can't usefully poll regular files. POLLIN and POLLOUT are >always true for
    a regular file.

    Regular files no, but its very useful when you're talking to something
    in /dev.

    Clearly you don't understand how multiplexing works in unix but given file >>I/O in userspace is buffered anyway you rarely need to multiplex file I/O >>unless its via NFS or similar.

    No high performance application will use stdio buffering.

    Obviously not. They'd use memory mapping, open the disk device directly
    or use some OS specific interface.


    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Michael S@3:633/10 to All on Thu Jul 9 22:15:53 2026
    On Thu, 9 Jul 2026 08:55:22 -0000 (UTC)
    boltar@caprica.universe wrote:

    On Wed, 8 Jul 2026 22:16:55 +0300
    Michael S <already5chosen@yahoo.com> gabbled:
    On Wed, 8 Jul 2026 09:34:40 -0000 (UTC)
    boltar@caprica.universe wrote:

    On Tue, 7 Jul 2026 20:36:11 +0300
    Michael S <already5chosen@yahoo.com> gabbled:
    On Tue, 7 Jul 2026 10:40:28 -0000 (UTC)
    boltar@caprica.universe wrote:
    Looks like windows maintains its own thread pool for a user
    which seems wasteful

    Why wasteful?
    If you don't use it, it costs you nothing.

    It costs the kernel time and resources or do you think its all done
    by magic pixies?


    It costs only if you use it.
    Otherwise, accordiing to my understanding, the only cost is few >zero-initialized fields in process control block.

    Whooosh....

    I don't understand what you mean.
    IMHO, portable *nix is the one that needs threads (or fork) for
    everything.

    Wtf are you talking about?

    I am talking about file IO. Was not it obvious?

    No it wasn't and no you don't need seperate threads to do file I/O ,
    you can simply multiplex the descriptors in select or poll just like
    sockets.

    Its quite possible - and I've done it a
    number of times - to write a network server in unix with a single
    thread & single process using multiplexed sockets via select() or
    poll().

    Then either files access in your server was blocking or you used >non-portable extensions to POSIX.

    Clearly you don't understand how multiplexing works in unix but given
    file I/O in userspace is buffered anyway you rarely need to multiplex
    file I/O unless its via NFS or similar.

    And it's not like on Windows it would be different. Except, may be,
    if you want to support very old versions of Windows (>20 y.o.) in >whichcasee you'll only have select() and no poll(). Which is
    inconvinience, but relatively minor one.

    select and poll are not an "inconvenience", they're fundamental to how
    single threaded servers are implemented on unix. Don't assume just
    because the windows versions are a pale shadow of the posix ones
    doesn't mean that they're useless.


    Your reading comprehension is so poor... :(
    So I'd speak sloooow.

    1. WinNt had select() from the very beginning (1993).
    Which is not surprising, considering that its original IP
    implementation was based on BSD.

    2. WinNt did not have pool()) until 2006.
    Which is not surprising, considering that it's original IP
    implementation was based on BSD.

    3. poll() is more convenient than select(), but functionality-wise
    everything that poll can do, select() can do as well.

    Do you understand now, or it was still too fast?













    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Chris M. Thomasson@3:633/10 to All on Thu Jul 9 12:51:04 2026
    On 7/9/2026 1:55 AM, boltar@caprica.universe wrote:
    On Wed, 8 Jul 2026 14:15:20 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/8/2026 2:34 AM, boltar@caprica.universe wrote:
    On Tue, 7 Jul 2026 20:36:11 +0300
    Michael S <already5chosen@yahoo.com> gabbled:
    On Tue, 7 Jul 2026 10:40:28 -0000 (UTC)
    boltar@caprica.universe wrote:
    Looks like windows maintains its own thread pool for a user which
    seems wasteful

    Why wasteful?
    If you don't use it, it costs you nothing.

    It costs the kernel time and resources or do you think its all done by
    magic pixies?

    HUH? If you don't create a thread pool in Windows, you are not using
    one. There is no cost. Sigh...

    And then the pool is created is just appears by magic, no setup required
    on the part of the OS?


    HUH!????? Wtf are you babbling on about, but really. Wow...

    We can create a thread pool. Or we can say okay we don't need one. We
    don't pay for one if we don't need one.

    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Chris M. Thomasson@3:633/10 to All on Thu Jul 9 12:53:39 2026
    On 7/9/2026 1:56 AM, boltar@caprica.universe wrote:
    On Wed, 8 Jul 2026 14:17:06 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/8/2026 2:38 AM, boltar@caprica.universe wrote:
    On Tue, 7 Jul 2026 15:17:01 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/7/2026 3:41 AM, boltar@caprica.universe wrote:
    On Mon, 6 Jul 2026 12:49:24 -0700
    So you don't have any code yet. Got it.


    You are too funny. wow. I think have posted a specialized one for a
    lock-free stack test here a couple of months ago. But, trust me. I
    know how to make them in many different forms. You think I am going
    to spend

    So you won't have a problem writing some short example code then will
    you.

    Oh, well, this is a specialized one I posted for an experimental
    futex based lock-free stack:

    I'm jnot wading through 270 lines of code. Demonstrate how "simple"
    thread
    pools are to implement or STFU.


    Huh? Make a thread pool is less than 20 lines? Are you daft?

    You were the one claiming how they were so simple to implement. But nice attempt at a back pedal.


    Oh my. You troll attempt is moronic. Sorry for the harsh lang. I did try
    to show you a little thread pool experiment for one of my experimental
    futex stacks, but you mocked it? So. Whatever. Its my fault that you do
    not know how to implement a simple thread pool. Wrt the one I need to
    impl, its method of gaining completions is based in the following
    function GetQueuedCompetionStatusEx.

    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Chris M. Thomasson@3:633/10 to All on Thu Jul 9 13:01:51 2026
    On 7/9/2026 1:34 AM, Bonita Montero wrote:
    Am 08.07.2026 um 23:32 schrieb Chris M. Thomasson:

    Not sure if a processor group can work with the power management or
    not. I think it can.

    OMG, what a nonsense.

    Not sure what MS means wrt:

    https://windowsreport.com/windows-11-hidden-cpu-setting-unlocks-advanced-performance-and-power-controls/

    https://learn.microsoft.com/en-us/windows/win32/procthread/cpu-sets

    "CPU Sets provide APIs to declare application affinity in a 'soft'
    manner that is compatible with OS power management. "

    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Keith Thompson@3:633/10 to All on Thu Jul 9 14:07:34 2026
    scott@slp53.sl.home (Scott Lurndal) writes:
    [...]
    Actually, you can't usefully poll regular files. POLLIN and POLLOUT
    are always true for a regular file.

    aio_read(2), aio_write(2) and lio_listio(2) provide asynchronous
    file I/O.
    [...]

    A small quibble: Those are library functions not system calls,
    at least on Linux with glibc. (As I'm sure you know, the "(2)"
    suffix denotes section 2 of the manual, which covers system calls.
    Section 3 covers library functions.)

    --
    Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
    void Void(void) { Void(); } /* The recursive call of the void */

    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Bonita Montero@3:633/10 to All on Fri Jul 10 05:58:36 2026
    Am 09.07.2026 um 22:01 schrieb Chris M. Thomasson:
    On 7/9/2026 1:34 AM, Bonita Montero wrote:
    Am 08.07.2026 um 23:32 schrieb Chris M. Thomasson:

    Not sure if a processor group can work with the power management or
    not. I think it can.

    OMG, what a nonsense.

    Not sure what MS means wrt:

    https://windowsreport.com/windows-11-hidden-cpu-setting-unlocks- advanced-performance-and-power-controls/

    https://learn.microsoft.com/en-us/windows/win32/procthread/cpu-sets

    "CPU Sets provide APIs to declare application affinity in a 'soft'
    manner that is compatible with OS power management. "

    CPU-affinities are a different topic.


    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Chris M. Thomasson@3:633/10 to All on Fri Jul 10 00:16:41 2026
    On 7/5/2026 8:49 AM, boltar@caprica.universe wrote:
    On Sun, 5 Jul 2026 01:22:34 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/5/2026 1:21 AM, boltar@caprica.universe wrote:
    On Sat, 4 Jul 2026 23:36:09 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/3/2026 1:59 AM, boltar@caprica.universe wrote:
    On Thu, 2 Jul 2026 11:41:48 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/2/2026 1:13 AM, boltar@caprica.universe wrote:
    They're hard enough to make it a lot of pointless work if its not >>>>>>> necessary. As I said, if you're creating threads every few
    milliseconds then
    use a thread pool. If you're just creating a thread every few
    seconds or longer then a pool is a complete waste of time.

    Thread per connection model? If that works for your work load, so >>>>>> be it. Just don't be alarmed if you get 10000 threads all of
    sudden. Or, say a connection comes in every second for say a half >>>>>> an hour. 1800 connections? Also you need to think about a
    connection that sends a little data then just sits there doing
    nothing for say 20 minutes.

    You do realise setting up and pulling down a TCP connection takes
    far more
    CPU resources than simply adding a new program counter into the
    scheduler
    list, right? If we were talking about creating a new process via
    fork() then
    your argument might have some merit, but threads? No.

    Why destroy the socket? Reuse it:

    TF_REUSE_SOCKET

    https://learn.microsoft.com/en-us/windows/win32/api/mswsock/nc-
    mswsock-lpfn_dis
    connectex

    I'm not interesting in win32, I only do posix and in posix a socket
    is simply
    an (indirect) integer index into a kernel network connection. Re-
    using one after

    the network connection has been closed makes no sense.


    Why? TF_REUSE_SOCKET is VERY useful.

    Why? Once its down a socket - in unix - is just an integer pointing to nothing.
    What difference does it make if the same value gets reused?


    TF_REUSE_SOCKET allows one to reuse a socket in a more efficient way. DisconnectEx. Fairly nice! Avoid calling WSASocket again.


    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From boltar@3:633/10 to All on Fri Jul 10 09:21:33 2026
    On Thu, 9 Jul 2026 22:15:53 +0300
    Michael S <already5chosen@yahoo.com> gabbled:
    3. poll() is more convenient than select(), but functionality-wise
    everything that poll can do, select() can do as well.

    Not entirely true. In select() the max descriptor value is limited to
    1 << FD_SETSIZE and the max number of monitored descriptors is FD_SETSIZE.
    In poll() these limits don't apply.


    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From boltar@3:633/10 to All on Fri Jul 10 09:22:33 2026
    On Thu, 9 Jul 2026 12:51:04 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/9/2026 1:55 AM, boltar@caprica.universe wrote:
    On Wed, 8 Jul 2026 14:15:20 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/8/2026 2:34 AM, boltar@caprica.universe wrote:
    On Tue, 7 Jul 2026 20:36:11 +0300
    Michael S <already5chosen@yahoo.com> gabbled:
    On Tue, 7 Jul 2026 10:40:28 -0000 (UTC)
    boltar@caprica.universe wrote:
    Looks like windows maintains its own thread pool for a user which
    seems wasteful

    Why wasteful?
    If you don't use it, it costs you nothing.

    It costs the kernel time and resources or do you think its all done by >>>> magic pixies?

    HUH? If you don't create a thread pool in Windows, you are not using
    one. There is no cost. Sigh...

    And then the pool is created is just appears by magic, no setup required
    on the part of the OS?


    HUH!????? Wtf are you babbling on about, but really. Wow...

    I could ask you the same question.

    We can create a thread pool. Or we can say okay we don't need one. We
    don't pay for one if we don't need one.

    No, but if you do need one there is a cost. I'm not sure why this is
    confusing you.


    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From boltar@3:633/10 to All on Fri Jul 10 09:24:16 2026
    On Thu, 9 Jul 2026 12:53:39 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/9/2026 1:56 AM, boltar@caprica.universe wrote:
    You were the one claiming how they were so simple to implement. But nice
    attempt at a back pedal.


    Oh my. You troll attempt is moronic. Sorry for the harsh lang. I did try
    to show you a little thread pool experiment for one of my experimental
    futex stacks, but you mocked it? So. Whatever. Its my fault that you do

    Go look up the definition of mocking. You said implementing a thread
    pool is simple then dump almost 300 lines of code as some kind of proof.
    I do not call that simple!

    not know how to implement a simple thread pool. Wrt the one I need to
    impl, its method of gaining completions is based in the following
    function GetQueuedCompetionStatusEx.

    I'm not interested in some win32 specific function, its irrelevant.


    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From boltar@3:633/10 to All on Fri Jul 10 09:25:12 2026
    On Fri, 10 Jul 2026 00:16:41 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/5/2026 8:49 AM, boltar@caprica.universe wrote:
    Why? Once its down a socket - in unix - is just an integer pointing to
    nothing.
    What difference does it make if the same value gets reused?


    TF_REUSE_SOCKET allows one to reuse a socket in a more efficient way. >DisconnectEx. Fairly nice! Avoid calling WSASocket again.

    Sounds like win32 is a whole other world. Thank god I never had to both with it.


    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Michael S@3:633/10 to All on Fri Jul 10 14:02:24 2026
    On Fri, 10 Jul 2026 09:21:33 -0000 (UTC)
    boltar@caprica.universe wrote:

    On Thu, 9 Jul 2026 22:15:53 +0300
    Michael S <already5chosen@yahoo.com> gabbled:
    3. poll() is more convenient than select(), but functionality-wise >everything that poll can do, select() can do as well.

    Not entirely true. In select() the max descriptor value is limited to
    1 << FD_SETSIZE and the max number of monitored descriptors is
    . In poll() these limits don't apply.


    Not on Windows.
    Windows copied BSD select() API, but implementation under the hood is different. Actually, now when I started to think about it,
    implementation-wise Winsock2 select() is very similar to poll().

    For starter, socket in Winsock2 is an integer number, but not *small*
    integer number.
    fd_set in Winsock2 is array of sockets rather than array of bits.
    One consequence of it is nfds parameter of select() is DNC.

    Max number of descriptors is indeed FD_SETSIZE (by default 64), but
    IIRC it can be changed by programmer via simple #define

    Also, apart from BSD-compatible select() Winsock2 provides two
    additional mechanism of waiting on multiple sockets.
    1. WsaAsyncSelect() associates socket with message queue of particular
    window. This mechanism is most applicable to simple single-threaded GUI applications.
    2. WSAEventSelect() associates socket with event object. That is most
    generic method that allows permits to combine waiting on socket with
    waiting on any other waitable object, most typically by means of WaitForMultipleObjects().

    Both methods exist from very begining of Win32/Winsock2 API.




    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Michael S@3:633/10 to All on Fri Jul 10 14:22:28 2026
    On Fri, 10 Jul 2026 09:22:33 -0000 (UTC)
    boltar@caprica.universe wrote:

    On Thu, 9 Jul 2026 12:51:04 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/9/2026 1:55 AM, boltar@caprica.universe wrote:
    On Wed, 8 Jul 2026 14:15:20 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/8/2026 2:34 AM, boltar@caprica.universe wrote:
    On Tue, 7 Jul 2026 20:36:11 +0300
    Michael S <already5chosen@yahoo.com> gabbled:
    On Tue, 7 Jul 2026 10:40:28 -0000 (UTC)
    boltar@caprica.universe wrote:
    Looks like windows maintains its own thread pool for a user
    which seems wasteful

    Why wasteful?
    If you don't use it, it costs you nothing.

    It costs the kernel time and resources or do you think its all
    done by magic pixies?

    HUH? If you don't create a thread pool in Windows, you are not
    using one. There is no cost. Sigh...

    And then the pool is created is just appears by magic, no setup
    required on the part of the OS?


    HUH!????? Wtf are you babbling on about, but really. Wow...

    I could ask you the same question.

    We can create a thread pool. Or we can say okay we don't need one.
    We don't pay for one if we don't need one.

    No, but if you do need one there is a cost. I'm not sure why this is confusing you.


    Of course, I would expect that when you call QueueUserWorkItem() for the
    first time, it will cost a little more than CreateThread(). And each
    time you call QueueUserWorkItem() when the pool is empty, it again
    costs a tiny bit more than CreateThread(). But in the latter case the difference is most likely undetectable.
    That's how pools work.
    If you don't expect that cases when pool is not empty on request are
    most common then don't use thread pool.

    The point of QueueUserWorkItem() is not doing some magic that the user
    can not on his own, but saving him programming time and bugs.








    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From boltar@3:633/10 to All on Fri Jul 10 11:22:52 2026
    On Fri, 10 Jul 2026 14:02:24 +0300
    Michael S <already5chosen@yahoo.com> gabbled:
    On Fri, 10 Jul 2026 09:21:33 -0000 (UTC)
    boltar@caprica.universe wrote:

    On Thu, 9 Jul 2026 22:15:53 +0300
    Michael S <already5chosen@yahoo.com> gabbled:
    3. poll() is more convenient than select(), but functionality-wise
    everything that poll can do, select() can do as well.

    Not entirely true. In select() the max descriptor value is limited to
    1 << FD_SETSIZE and the max number of monitored descriptors is
    . In poll() these limits don't apply.


    Not on Windows.
    Windows copied BSD select() API, but implementation under the hood is >different. Actually, now when I started to think about it, >implementation-wise Winsock2 select() is very similar to poll().

    For starter, socket in Winsock2 is an integer number, but not *small*
    integer number.
    fd_set in Winsock2 is array of sockets rather than array of bits.

    Then it clearly no longer uses the BSD API because BSD select() multiplexes integer descriptors, not socket structures, otherwise it couldn't also multiplex pipes, fifos etc.

    1. WsaAsyncSelect() associates socket with message queue of particular >window. This mechanism is most applicable to simple single-threaded GUI >applications.

    Huh? Why on earth would a window care about socket data? Actually, I don't care, Windows is such a bizarre OS that I'd rather keep my sanity.


    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From boltar@3:633/10 to All on Fri Jul 10 11:24:50 2026
    On Fri, 10 Jul 2026 14:22:28 +0300
    Michael S <already5chosen@yahoo.com> gabbled:
    On Fri, 10 Jul 2026 09:22:33 -0000 (UTC)
    boltar@caprica.universe wrote:
    No, but if you do need one there is a cost. I'm not sure why this is
    confusing you.


    Of course, I would expect that when you call QueueUserWorkItem() for the >first time, it will cost a little more than CreateThread(). And each
    time you call QueueUserWorkItem() when the pool is empty, it again
    costs a tiny bit more than CreateThread(). But in the latter case the >difference is most likely undetectable.

    A pool is more than just an array of threads or you could simply do

    vector<thread> mypool;

    and call it a day. Thread pools have to be managed and that can be non trivial.


    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Michael S@3:633/10 to All on Fri Jul 10 14:45:40 2026
    On Fri, 10 Jul 2026 11:22:52 -0000 (UTC)
    boltar@caprica.universe wrote:

    On Fri, 10 Jul 2026 14:02:24 +0300
    Michael S <already5chosen@yahoo.com> gabbled:
    On Fri, 10 Jul 2026 09:21:33 -0000 (UTC)
    boltar@caprica.universe wrote:

    On Thu, 9 Jul 2026 22:15:53 +0300
    Michael S <already5chosen@yahoo.com> gabbled:
    3. poll() is more convenient than select(), but functionality-wise
    everything that poll can do, select() can do as well.

    Not entirely true. In select() the max descriptor value is limited
    to 1 << FD_SETSIZE and the max number of monitored descriptors is
    . In poll() these limits don't apply.


    Not on Windows.
    Windows copied BSD select() API, but implementation under the hood is >different. Actually, now when I started to think about it, >implementation-wise Winsock2 select() is very similar to poll().

    For starter, socket in Winsock2 is an integer number, but not *small* >integer number.
    fd_set in Winsock2 is array of sockets rather than array of bits.

    Then it clearly no longer uses the BSD API because BSD select()
    multiplexes integer descriptors, not socket structures, otherwise it
    couldn't also multiplex pipes, fifos etc.

    1. WsaAsyncSelect() associates socket with message queue of
    particular window. This mechanism is most applicable to simple >single-threaded GUI applications.

    Huh? Why on earth would a window care about socket data?

    Think client, not server.
    For example, telnet client in hyperterminal.
    [O.T.]
    Hyperterminal was rather buggy. Despite that I encountered many people
    that liked it so much that they went to trouble of installing it on
    Win7 and may be even later.
    [/O.T.]

    Actually, I
    don't care, Windows is such a bizarre OS that I'd rather keep my
    sanity.


    That's o.k.
    Spouting uninformed statements about something you don't care about like
    the one that started this particular sub-thread is less o.k. as far as
    I am concerned.
    But if you enjoj it then go on.









    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From boltar@3:633/10 to All on Fri Jul 10 15:12:08 2026
    On Fri, 10 Jul 2026 14:45:40 +0300
    Michael S <already5chosen@yahoo.com> gabbled:
    On Fri, 10 Jul 2026 11:22:52 -0000 (UTC)
    boltar@caprica.universe wrote:
    Huh? Why on earth would a window care about socket data?

    Think client, not server.

    I'm thinking window - its a graphical object, just like a bitmap. Why TF
    would it care about data of any sort?

    Actually, I
    don't care, Windows is such a bizarre OS that I'd rather keep my
    sanity.


    That's o.k.
    Spouting uninformed statements about something you don't care about like
    the one that started this particular sub-thread is less o.k. as far as
    I am concerned.
    But if you enjoj it then go on.

    I seem to know more about thread pools than some people on here who make
    hand waving statements about how "simple" they are then don't provide any simple code to back that statement up.


    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Scott Lurndal@3:633/10 to All on Fri Jul 10 15:32:45 2026
    boltar@caprica.universe writes:
    On Thu, 09 Jul 2026 15:18:38 GMT
    scott@slp53.sl.home (Scott Lurndal) gabbled:
    boltar@caprica.universe writes:
    No it wasn't and no you don't need seperate threads to do file I/O , you >>>can simply multiplex the descriptors in select or poll just like sockets.

    Actually, you can't usefully poll regular files. POLLIN and POLLOUT are >>always true for
    a regular file.

    Regular files no, but its very useful when you're talking to something
    in /dev.

    Not really. Block devices are always POLLIN and POLLOUT ready.

    Some character devices (serial ports for example) may
    support the O_NONBLOCK fcntl flag and thus be usable with poll/select.

    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Scott Lurndal@3:633/10 to All on Fri Jul 10 15:34:06 2026
    Keith Thompson <Keith.S.Thompson+u@gmail.com> writes:
    scott@slp53.sl.home (Scott Lurndal) writes:
    [...]
    Actually, you can't usefully poll regular files. POLLIN and POLLOUT
    are always true for a regular file.

    aio_read(2), aio_write(2) and lio_listio(2) provide asynchronous
    file I/O.
    [...]

    A small quibble: Those are library functions not system calls,
    at least on Linux with glibc. (As I'm sure you know, the "(2)"
    suffix denotes section 2 of the manual, which covers system calls.
    Section 3 covers library functions.)

    They are implemented as system calls on SVR4/Unixware, SVR4/MK
    and IIRC Solaris.


    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Michael S@3:633/10 to All on Fri Jul 10 18:43:37 2026
    On Fri, 10 Jul 2026 15:12:08 -0000 (UTC)
    boltar@caprica.universe wrote:

    On Fri, 10 Jul 2026 14:45:40 +0300
    Michael S <already5chosen@yahoo.com> gabbled:
    On Fri, 10 Jul 2026 11:22:52 -0000 (UTC)
    boltar@caprica.universe wrote:
    Huh? Why on earth would a window care about socket data?

    Think client, not server.

    I'm thinking window - its a graphical object, just like a bitmap. Why
    TF would it care about data of any sort?


    I don't know what is meaning of window in your preferred GUI
    environment. But on Windows 'window' is not 'graphical' object and not
    similar to bitmap. It is a graphical user interface object. The most
    prominent feature of window object is "message pump" with its
    associated message queue.
    Window is commonly visible, but it does not have to be. Invisible
    windows that are used purely for sake of they message pump/queue are
    not uncommon.
    Window-related functions are exported through User32.dll which is
    distinct from GDI32.dll responsible for graphics and from Kernel32.dll
    which exports basic OS services.

    Actually, I
    don't care, Windows is such a bizarre OS that I'd rather keep my
    sanity.


    That's o.k.
    Spouting uninformed statements about something you don't care about
    like the one that started this particular sub-thread is less o.k. as
    far as I am concerned.
    But if you enjoj it then go on.

    I seem to know more about thread pools than some people on here who
    make hand waving statements about how "simple" they are then don't
    provide any simple code to back that statement up.


    I was talking about part of thread that started when you wrote
    "understandable in an OS that seems to require threads for everything".


    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From boltar@3:633/10 to All on Fri Jul 10 16:03:12 2026
    On Fri, 10 Jul 2026 15:32:45 GMT
    scott@slp53.sl.home (Scott Lurndal) gabbled:
    boltar@caprica.universe writes:
    On Thu, 09 Jul 2026 15:18:38 GMT
    scott@slp53.sl.home (Scott Lurndal) gabbled:
    boltar@caprica.universe writes:
    No it wasn't and no you don't need seperate threads to do file I/O , you >>>>can simply multiplex the descriptors in select or poll just like sockets. >>>
    Actually, you can't usefully poll regular files. POLLIN and POLLOUT are >>>always true for
    a regular file.

    Regular files no, but its very useful when you're talking to something
    in /dev.

    Not really. Block devices are always POLLIN and POLLOUT ready.

    Some character devices (serial ports for example) may
    support the O_NONBLOCK fcntl flag and thus be usable with poll/select.

    I've done multiplexing on character devices, select() works just fine. Not
    sure why you're wibbling about the NONBLOCK flag, its irrelevant in this situation.


    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From boltar@3:633/10 to All on Fri Jul 10 16:06:47 2026
    On Fri, 10 Jul 2026 18:43:37 +0300
    Michael S <already5chosen@yahoo.com> gabbled:
    On Fri, 10 Jul 2026 15:12:08 -0000 (UTC)
    boltar@caprica.universe wrote:
    I'm thinking window - its a graphical object, just like a bitmap. Why
    TF would it care about data of any sort?


    I don't know what is meaning of window in your preferred GUI
    environment. But on Windows 'window' is not 'graphical' object and not >similar to bitmap. It is a graphical user interface object. The most

    In X Windows a window is an area of screen that has a window outline and returns events. Want to process data? Do it elsewhere, the window isn't interested.

    prominent feature of window object is "message pump" with its
    associated message queue.
    Window is commonly visible, but it does not have to be. Invisible
    windows that are used purely for sake of they message pump/queue are
    not uncommon.
    Window-related functions are exported through User32.dll which is
    distinct from GDI32.dll responsible for graphics and from Kernel32.dll
    which exports basic OS services.

    I knew MSWin was wierd but its design just sounds fucking bizarre, like something dreamt up by someone on LSD. Why TF would you want an on
    screen object to do processing? What else, does a sound get sent data too
    in Windows?

    I seem to know more about thread pools than some people on here who
    make hand waving statements about how "simple" they are then don't
    provide any simple code to back that statement up.


    I was talking about part of thread that started when you wrote >"understandable in an OS that seems to require threads for everything".

    Perhaps be clearer then.


    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Michael S@3:633/10 to All on Fri Jul 10 19:13:06 2026
    On Fri, 10 Jul 2026 16:06:47 -0000 (UTC)
    boltar@caprica.universe wrote:

    On Fri, 10 Jul 2026 18:43:37 +0300
    Michael S <already5chosen@yahoo.com> gabbled:
    On Fri, 10 Jul 2026 15:12:08 -0000 (UTC)
    boltar@caprica.universe wrote:
    I'm thinking window - its a graphical object, just like a bitmap.
    Why TF would it care about data of any sort?


    I don't know what is meaning of window in your preferred GUI
    environment. But on Windows 'window' is not 'graphical' object and
    not similar to bitmap. It is a graphical user interface object. The
    most

    In X Windows a window is an area of screen that has a window outline
    and returns events. Want to process data? Do it elsewhere, the window
    isn't interested.


    X is a bad point of comparison - too low level.
    Think X-Motif. It is the same era as User32 and likely has similar
    concepts. Not that I ever looked.


    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Chris M. Thomasson@3:633/10 to All on Fri Jul 10 12:32:18 2026
    On 7/10/2026 4:24 AM, boltar@caprica.universe wrote:
    On Fri, 10 Jul 2026 14:22:28 +0300
    Michael S <already5chosen@yahoo.com> gabbled:
    On Fri, 10 Jul 2026 09:22:33 -0000 (UTC)
    boltar@caprica.universe wrote:
    No, but if you do need one there is a cost. I'm not sure why this is
    confusing you.


    Of course, I would expect that when you call QueueUserWorkItem() for the
    first time, it will cost a little more than CreateThread(). And each
    time you call QueueUserWorkItem() when the pool is empty, it again
    costs a tiny bit more than CreateThread(). But in the latter case the
    difference is most likely undetectable.

    A pool is more than just an array of threads or you could simply do

    vector<thread> mypool;

    and call it a day. Thread pools have to be managed and that can be non trivial.


    Sigh. Knowing how to use threads is a first step! Then lets create a
    pool. So, you need to know how to use threads first, and yes that
    involves know how to sync them.

    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Chris M. Thomasson@3:633/10 to All on Fri Jul 10 13:36:52 2026
    On 7/10/2026 2:24 AM, boltar@caprica.universe wrote:
    On Thu, 9 Jul 2026 12:53:39 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/9/2026 1:56 AM, boltar@caprica.universe wrote:
    You were the one claiming how they were so simple to implement. But
    nice attempt at a back pedal.


    Oh my. You troll attempt is moronic. Sorry for the harsh lang. I did
    try to show you a little thread pool experiment for one of my
    experimental futex stacks, but you mocked it? So. Whatever. Its my
    fault that you do

    Go look up the definition of mocking. You said implementing a thread
    pool is simple then dump almost 300 lines of code as some kind of proof.
    I do not call that simple!

    Sigh. You want things so simple as to have a machine to wipe your butt?
    Or something? What are you talking about here!




    not know how to implement a simple thread pool. Wrt the one I need to
    impl, its method of gaining completions is based in the following
    function GetQueuedCompetionStatusEx.

    I'm not interested in some win32 specific function, its irrelevant.



    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Chris M. Thomasson@3:633/10 to All on Fri Jul 10 15:33:04 2026
    On 7/10/2026 4:02 AM, Michael S wrote:
    On Fri, 10 Jul 2026 09:21:33 -0000 (UTC)
    boltar@caprica.universe wrote:

    On Thu, 9 Jul 2026 22:15:53 +0300
    Michael S <already5chosen@yahoo.com> gabbled:
    3. poll() is more convenient than select(), but functionality-wise
    everything that poll can do, select() can do as well.

    Not entirely true. In select() the max descriptor value is limited to
    1 << FD_SETSIZE and the max number of monitored descriptors is
    . In poll() these limits don't apply.


    Not on Windows.
    Windows copied BSD select() API, but implementation under the hood is different. Actually, now when I started to think about it, implementation-wise Winsock2 select() is very similar to poll().

    For starter, socket in Winsock2 is an integer number, but not *small*
    integer number.
    fd_set in Winsock2 is array of sockets rather than array of bits.
    One consequence of it is nfds parameter of select() is DNC.

    Max number of descriptors is indeed FD_SETSIZE (by default 64), but
    IIRC it can be changed by programmer via simple #define

    Also, apart from BSD-compatible select() Winsock2 provides two
    additional mechanism of waiting on multiple sockets.
    1. WsaAsyncSelect() associates socket with message queue of particular window. This mechanism is most applicable to simple single-threaded GUI applications.
    2. WSAEventSelect() associates socket with event object. That is most
    generic method that allows permits to combine waiting on socket with
    waiting on any other waitable object, most typically by means of WaitForMultipleObjects().

    Both methods exist from very begining of Win32/Winsock2 API.




    GetQueuedCompletionStausEx is the one "modern" way to wait on SOCKET's, FILE's, etc...

    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Chris M. Thomasson@3:633/10 to All on Fri Jul 10 15:33:52 2026
    On 7/10/2026 4:02 AM, Michael S wrote:
    On Fri, 10 Jul 2026 09:21:33 -0000 (UTC)
    boltar@caprica.universe wrote:

    On Thu, 9 Jul 2026 22:15:53 +0300
    Michael S <already5chosen@yahoo.com> gabbled:
    3. poll() is more convenient than select(), but functionality-wise
    everything that poll can do, select() can do as well.

    Not entirely true. In select() the max descriptor value is limited to
    1 << FD_SETSIZE and the max number of monitored descriptors is
    . In poll() these limits don't apply.


    Not on Windows.
    Windows copied BSD select() API, but implementation under the hood is different. Actually, now when I started to think about it, implementation-wise Winsock2 select() is very similar to poll().

    For starter, socket in Winsock2 is an integer number, but not *small*
    integer number.
    fd_set in Winsock2 is array of sockets rather than array of bits.
    One consequence of it is nfds parameter of select() is DNC.

    Max number of descriptors is indeed FD_SETSIZE (by default 64), but
    IIRC it can be changed by programmer via simple #define

    Also, apart from BSD-compatible select() Winsock2 provides two
    additional mechanism of waiting on multiple sockets.
    1. WsaAsyncSelect() associates socket with message queue of particular window. This mechanism is most applicable to simple single-threaded GUI applications.
    2. WSAEventSelect() associates socket with event object. That is most
    generic method that allows permits to combine waiting on socket with
    waiting on any other waitable object, most typically by means of WaitForMultipleObjects().

    Both methods exist from very begining of Win32/Winsock2 API.




    Beware of WaitForMultipleObjects. You need to move the handles around or
    else starvation can occur!

    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Chris M. Thomasson@3:633/10 to All on Fri Jul 10 15:36:42 2026
    On 7/10/2026 2:25 AM, boltar@caprica.universe wrote:
    On Fri, 10 Jul 2026 00:16:41 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/5/2026 8:49 AM, boltar@caprica.universe wrote:
    Why? Once its down a socket - in unix - is just an integer pointing
    to nothing.
    What difference does it make if the same value gets reused?


    TF_REUSE_SOCKET allows one to reuse a socket in a more efficient way.
    DisconnectEx. Fairly nice! Avoid calling WSASocket again.

    Sounds like win32 is a whole other world. Thank god I never had to both
    with it.


    Fair enough. Reusing a socket is nothing new, right?

    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From boltar@3:633/10 to All on Sat Jul 11 09:28:40 2026
    On Fri, 10 Jul 2026 19:13:06 +0300
    Michael S <already5chosen@yahoo.com> gabbled:
    On Fri, 10 Jul 2026 16:06:47 -0000 (UTC)
    boltar@caprica.universe wrote:

    On Fri, 10 Jul 2026 18:43:37 +0300
    Michael S <already5chosen@yahoo.com> gabbled:
    On Fri, 10 Jul 2026 15:12:08 -0000 (UTC)
    boltar@caprica.universe wrote:
    I'm thinking window - its a graphical object, just like a bitmap.
    Why TF would it care about data of any sort?


    I don't know what is meaning of window in your preferred GUI
    environment. But on Windows 'window' is not 'graphical' object and
    not similar to bitmap. It is a graphical user interface object. The
    most

    In X Windows a window is an area of screen that has a window outline
    and returns events. Want to process data? Do it elsewhere, the window
    isn't interested.


    X is a bad point of comparison - too low level.
    Think X-Motif. It is the same era as User32 and likely has similar
    concepts. Not that I ever looked.

    All callbacks I've used in GUI libraries on top of X are simply event based
    for widgets to capture. I've never come across one where on screen objects suddely got promoted to doing their own processing of data and why would
    they - the X server is simple a graphics server and doesn't even have to
    run on the same machine as the program using it.

    Having a window deal with data just seems a moronic paradigm to me - what if more than 1 window needs it or the main core application? Ridiculous.


    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From boltar@3:633/10 to All on Sat Jul 11 09:29:46 2026
    On Fri, 10 Jul 2026 12:32:18 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/10/2026 4:24 AM, boltar@caprica.universe wrote:
    On Fri, 10 Jul 2026 14:22:28 +0300
    Michael S <already5chosen@yahoo.com> gabbled:
    On Fri, 10 Jul 2026 09:22:33 -0000 (UTC)
    boltar@caprica.universe wrote:
    No, but if you do need one there is a cost. I'm not sure why this is
    confusing you.


    Of course, I would expect that when you call QueueUserWorkItem() for the >>> first time, it will cost a little more than CreateThread(). And each
    time you call QueueUserWorkItem() when the pool is empty, it again
    costs a tiny bit more than CreateThread(). But in the latter case the
    difference is most likely undetectable.

    A pool is more than just an array of threads or you could simply do

    vector<thread> mypool;

    and call it a day. Thread pools have to be managed and that can be non >trivial.


    Sigh. Knowing how to use threads is a first step! Then lets create a
    pool. So, you need to know how to use threads first, and yes that
    involves know how to sync them.

    No shit Sherlock, did you get help from Watson with that one? Whats it got
    to do with ease of implemtation:?


    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From boltar@3:633/10 to All on Sat Jul 11 09:30:50 2026
    On Fri, 10 Jul 2026 13:36:52 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/10/2026 2:24 AM, boltar@caprica.universe wrote:
    On Thu, 9 Jul 2026 12:53:39 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/9/2026 1:56 AM, boltar@caprica.universe wrote:
    You were the one claiming how they were so simple to implement. But
    nice attempt at a back pedal.


    Oh my. You troll attempt is moronic. Sorry for the harsh lang. I did
    try to show you a little thread pool experiment for one of my
    experimental futex stacks, but you mocked it? So. Whatever. Its my
    fault that you do

    Go look up the definition of mocking. You said implementing a thread
    pool is simple then dump almost 300 lines of code as some kind of proof.
    I do not call that simple!

    Sigh. You want things so simple as to have a machine to wipe your butt?
    Or something? What are you talking about here!

    I could ask you the same question. Perhaps your comprehension of english isn't as good as you think because I thought I was being pretty clear. Anyway, I can't be bothered going around in circles any more, suffice to say thread
    pools are not simple to implement and never will be.


    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From boltar@3:633/10 to All on Sat Jul 11 09:32:56 2026
    On Fri, 10 Jul 2026 15:36:42 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/10/2026 2:25 AM, boltar@caprica.universe wrote:
    On Fri, 10 Jul 2026 00:16:41 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/5/2026 8:49 AM, boltar@caprica.universe wrote:
    Why? Once its down a socket - in unix - is just an integer pointing
    to nothing.
    What difference does it make if the same value gets reused?


    TF_REUSE_SOCKET allows one to reuse a socket in a more efficient way.
    DisconnectEx. Fairly nice! Avoid calling WSASocket again.

    Sounds like win32 is a whole other world. Thank god I never had to both
    with it.


    Fair enough. Reusing a socket is nothing new, right?

    On *nix a socket is simply a integer key into the lower level networking subsystem. Re-using once the link it was the key for has been closed makes no sense. You may well get the same integer value if you close a socket then
    open a new one but its irrelevant.


    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Chris M. Thomasson@3:633/10 to All on Sat Jul 11 14:08:05 2026
    On 7/11/2026 2:30 AM, boltar@caprica.universe wrote:
    On Fri, 10 Jul 2026 13:36:52 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/10/2026 2:24 AM, boltar@caprica.universe wrote:
    On Thu, 9 Jul 2026 12:53:39 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/9/2026 1:56 AM, boltar@caprica.universe wrote:
    You were the one claiming how they were so simple to implement. But >>>>> nice attempt at a back pedal.


    Oh my. You troll attempt is moronic. Sorry for the harsh lang. I did
    try to show you a little thread pool experiment for one of my
    experimental futex stacks, but you mocked it? So. Whatever. Its my
    fault that you do

    Go look up the definition of mocking. You said implementing a thread
    pool is simple then dump almost 300 lines of code as some kind of proof. >>> I do not call that simple!

    Sigh. You want things so simple as to have a machine to wipe your
    butt? Or something? What are you talking about here!

    I could ask you the same question. Perhaps your comprehension of english isn't
    as good as you think because I thought I was being pretty clear. Anyway, I can't be bothered going around in circles any more, suffice to say thread pools are not simple to implement and never will be.


    Knowing what you are doing is the main battle.

    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Chris M. Thomasson@3:633/10 to All on Sat Jul 11 14:09:51 2026
    On 7/11/2026 2:29 AM, boltar@caprica.universe wrote:
    On Fri, 10 Jul 2026 12:32:18 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/10/2026 4:24 AM, boltar@caprica.universe wrote:
    On Fri, 10 Jul 2026 14:22:28 +0300
    Michael S <already5chosen@yahoo.com> gabbled:
    On Fri, 10 Jul 2026 09:22:33 -0000 (UTC)
    boltar@caprica.universe wrote:
    No, but if you do need one there is a cost. I'm not sure why this is >>>>> confusing you.


    Of course, I would expect that when you call QueueUserWorkItem() for
    the
    first time, it will cost a little more than CreateThread(). And each
    time you call QueueUserWorkItem() when the pool is empty, it again
    costs a tiny bit more than CreateThread(). But in the latter case the
    difference is most likely undetectable.

    A pool is more than just an array of threads or you could simply do

    vector<thread> mypool;

    and call it a day. Thread pools have to be managed and that can be non
    trivial.


    Sigh. Knowing how to use threads is a first step! Then lets create a
    pool. So, you need to know how to use threads first, and yes that
    involves know how to sync them.

    No shit Sherlock, did you get help from Watson with that one? Whats it got
    to do with ease of implemtation:?


    Ease is relative. Hard for you perhaps?

    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Chris M. Thomasson@3:633/10 to All on Sat Jul 11 14:10:20 2026
    On 7/11/2026 2:32 AM, boltar@caprica.universe wrote:
    On Fri, 10 Jul 2026 15:36:42 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/10/2026 2:25 AM, boltar@caprica.universe wrote:
    On Fri, 10 Jul 2026 00:16:41 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/5/2026 8:49 AM, boltar@caprica.universe wrote:
    Why? Once its down a socket - in unix - is just an integer pointing >>>>> to nothing.
    What difference does it make if the same value gets reused?


    TF_REUSE_SOCKET allows one to reuse a socket in a more efficient
    way. DisconnectEx. Fairly nice! Avoid calling WSASocket again.

    Sounds like win32 is a whole other world. Thank god I never had to
    both with it.


    Fair enough. Reusing a socket is nothing new, right?

    On *nix a socket is simply a integer key into the lower level networking subsystem. Re-using once the link it was the key for has been closed
    makes no sense. You may well get the same integer value if you close a socket then
    open a new one but its irrelevant.


    Reusing a socket make a heck of a lot of sense indeed!

    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Chris M. Thomasson@3:633/10 to All on Sat Jul 11 14:11:15 2026
    On 7/11/2026 2:32 AM, boltar@caprica.universe wrote:
    On Fri, 10 Jul 2026 15:36:42 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/10/2026 2:25 AM, boltar@caprica.universe wrote:
    On Fri, 10 Jul 2026 00:16:41 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/5/2026 8:49 AM, boltar@caprica.universe wrote:
    Why? Once its down a socket - in unix - is just an integer pointing >>>>> to nothing.
    What difference does it make if the same value gets reused?


    TF_REUSE_SOCKET allows one to reuse a socket in a more efficient
    way. DisconnectEx. Fairly nice! Avoid calling WSASocket again.

    Sounds like win32 is a whole other world. Thank god I never had to
    both with it.


    Fair enough. Reusing a socket is nothing new, right?

    On *nix a socket is simply a integer key into the lower level networking subsystem. Re-using once the link it was the key for has been closed
    makes no sense. You may well get the same integer value if you close a socket then
    open a new one but its irrelevant.


    After a DisconnctEx returns successfully, the socket in question can be
    reused for AcceptEx or ConnectEx. No need to call WSASocket to make a
    new one.

    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Chris M. Thomasson@3:633/10 to All on Sat Jul 11 14:41:04 2026
    On 7/11/2026 2:28 AM, boltar@caprica.universe wrote:
    On Fri, 10 Jul 2026 19:13:06 +0300
    Michael S <already5chosen@yahoo.com> gabbled:
    On Fri, 10 Jul 2026 16:06:47 -0000 (UTC)
    boltar@caprica.universe wrote:

    On Fri, 10 Jul 2026 18:43:37 +0300
    Michael S <already5chosen@yahoo.com> gabbled:
    On Fri, 10 Jul 2026 15:12:08 -0000 (UTC)
    boltar@caprica.universe wrote:
    I'm thinking window - its a graphical object, just like a bitmap.
    Why TF would it care about data of any sort?


    I don't know what is meaning of window in your preferred GUI
    environment. But on Windows 'window' is not 'graphical' object and
    not similar to bitmap. It is a graphical user interface object. The
    most

    In X Windows a window is an area of screen that has a window outline
    and returns events. Want to process data? Do it elsewhere, the window
    isn't interested.


    X is a bad point of comparison - too low level.
    Think X-Motif. It is the same era as User32 and likely has similar
    concepts. Not that I ever looked.

    All callbacks I've used in GUI libraries on top of X are simply event based for widgets to capture. I've never come across one where on screen objects suddely got promoted to doing their own processing of data and why would
    they - the X server is simple a graphics server and doesn't even have to
    run on the same machine as the program using it.

    Having a window deal with data just seems a moronic paradigm to me - what if more than 1 window needs it or the main core application? Ridiculous.


    Create two windows that use the same core app/data?

    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From boltar@3:633/10 to All on Sun Jul 12 15:15:30 2026
    On Sat, 11 Jul 2026 14:09:51 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/11/2026 2:29 AM, boltar@caprica.universe wrote:
    On Fri, 10 Jul 2026 12:32:18 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/10/2026 4:24 AM, boltar@caprica.universe wrote:
    On Fri, 10 Jul 2026 14:22:28 +0300
    Michael S <already5chosen@yahoo.com> gabbled:
    On Fri, 10 Jul 2026 09:22:33 -0000 (UTC)
    boltar@caprica.universe wrote:
    No, but if you do need one there is a cost. I'm not sure why this is >>>>>> confusing you.


    Of course, I would expect that when you call QueueUserWorkItem() for >>>>> the
    first time, it will cost a little more than CreateThread(). And each >>>>> time you call QueueUserWorkItem() when the pool is empty, it again
    costs a tiny bit more than CreateThread(). But in the latter case the >>>>> difference is most likely undetectable.

    A pool is more than just an array of threads or you could simply do

    vector<thread> mypool;

    and call it a day. Thread pools have to be managed and that can be non
    trivial.


    Sigh. Knowing how to use threads is a first step! Then lets create a
    pool. So, you need to know how to use threads first, and yes that
    involves know how to sync them.

    No shit Sherlock, did you get help from Watson with that one? Whats it got >> to do with ease of implemtation:?


    Ease is relative. Hard for you perhaps?

    Yes, its relative to creating a thread then detaching. 2 lines of C++, not
    much more in C. So, as I keep asking, show us your "simple" pool code.


    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From boltar@3:633/10 to All on Sun Jul 12 15:18:30 2026
    On Sat, 11 Jul 2026 14:10:20 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/11/2026 2:32 AM, boltar@caprica.universe wrote:
    On Fri, 10 Jul 2026 15:36:42 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/10/2026 2:25 AM, boltar@caprica.universe wrote:
    On Fri, 10 Jul 2026 00:16:41 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/5/2026 8:49 AM, boltar@caprica.universe wrote:
    Why? Once its down a socket - in unix - is just an integer pointing >>>>>> to nothing.
    What difference does it make if the same value gets reused?


    TF_REUSE_SOCKET allows one to reuse a socket in a more efficient
    way. DisconnectEx. Fairly nice! Avoid calling WSASocket again.

    Sounds like win32 is a whole other world. Thank god I never had to
    both with it.


    Fair enough. Reusing a socket is nothing new, right?

    On *nix a socket is simply a integer key into the lower level networking
    subsystem. Re-using once the link it was the key for has been closed
    makes no sense. You may well get the same integer value if you close a
    socket then
    open a new one but its irrelevant.


    Reusing a socket make a heck of a lot of sense indeed!

    Maybe in Win32. On *nix its not only pointless, its meaningless. Sockets
    don't exist in any sense other than being an id for a connection. I suppose
    a hacker might like to close a connection in a hacked library , re-open a new one to their server and present the same socket id to the user application
    but I can't think of any other "use".


    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From boltar@3:633/10 to All on Sun Jul 12 15:19:52 2026
    On Sat, 11 Jul 2026 14:11:15 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/11/2026 2:32 AM, boltar@caprica.universe wrote:
    On Fri, 10 Jul 2026 15:36:42 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/10/2026 2:25 AM, boltar@caprica.universe wrote:
    On Fri, 10 Jul 2026 00:16:41 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/5/2026 8:49 AM, boltar@caprica.universe wrote:
    Why? Once its down a socket - in unix - is just an integer pointing >>>>>> to nothing.
    What difference does it make if the same value gets reused?


    TF_REUSE_SOCKET allows one to reuse a socket in a more efficient
    way. DisconnectEx. Fairly nice! Avoid calling WSASocket again.

    Sounds like win32 is a whole other world. Thank god I never had to
    both with it.


    Fair enough. Reusing a socket is nothing new, right?

    On *nix a socket is simply a integer key into the lower level networking
    subsystem. Re-using once the link it was the key for has been closed
    makes no sense. You may well get the same integer value if you close a
    socket then
    open a new one but its irrelevant.


    After a DisconnctEx returns successfully, the socket in question can be >reused for AcceptEx or ConnectEx. No need to call WSASocket to make a
    new one.

    Seems WSASocket() returns a structure with a whole load of crap in it unlike posix socket() which returns an int. So maybe in win32 it does make sense.


    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From boltar@3:633/10 to All on Sun Jul 12 15:23:20 2026
    On Sat, 11 Jul 2026 14:41:04 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/11/2026 2:28 AM, boltar@caprica.universe wrote:
    On Fri, 10 Jul 2026 19:13:06 +0300
    Having a window deal with data just seems a moronic paradigm to me - what if >> more than 1 window needs it or the main core application? Ridiculous.


    Create two windows that use the same core app/data?

    I meant who gets the data first and what if the logic in one "window"
    conflicts with another. What a mess. Just have some graphic objects and a couple of core threads, one deals with graphics events and callbacks, the other does everything else. At least thats how graphical applications are written on sane OS's, not some toy that evolved from a disk monitor.


    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Chris M. Thomasson@3:633/10 to All on Sun Jul 12 10:58:55 2026
    On 7/12/2026 8:15 AM, boltar@caprica.universe wrote:
    On Sat, 11 Jul 2026 14:09:51 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    [...]
    Ease is relative. Hard for you perhaps?

    Yes, its relative to creating a thread then detaching. 2 lines of C++, not much more in C. So, as I keep asking, show us your "simple" pool code.


    I don't work for you. I already showed you a little thread pool using my experimental lock-free stack, you mocked it. I am working on some other
    things right now. Fwiw, check this shit out:

    https://skfb.ly/pyP9E

    https://skfb.ly/pyXH6

    https://skfb.ly/pzTEC

    Can your system view these?

    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Chris M. Thomasson@3:633/10 to All on Sun Jul 12 11:02:53 2026
    On 7/12/2026 8:19 AM, boltar@caprica.universe wrote:
    On Sat, 11 Jul 2026 14:11:15 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/11/2026 2:32 AM, boltar@caprica.universe wrote:
    On Fri, 10 Jul 2026 15:36:42 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/10/2026 2:25 AM, boltar@caprica.universe wrote:
    On Fri, 10 Jul 2026 00:16:41 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/5/2026 8:49 AM, boltar@caprica.universe wrote:
    Why? Once its down a socket - in unix - is just an integer
    pointing to nothing.
    What difference does it make if the same value gets reused?


    TF_REUSE_SOCKET allows one to reuse a socket in a more efficient
    way. DisconnectEx. Fairly nice! Avoid calling WSASocket again.

    Sounds like win32 is a whole other world. Thank god I never had to
    both with it.


    Fair enough. Reusing a socket is nothing new, right?

    On *nix a socket is simply a integer key into the lower level networking >>> subsystem. Re-using once the link it was the key for has been closed
    makes no sense. You may well get the same integer value if you close
    a socket then
    open a new one but its irrelevant.


    After a DisconnctEx returns successfully, the socket in question can
    be reused for AcceptEx or ConnectEx. No need to call WSASocket to make
    a new one.

    Seems WSASocket() returns a structure with a whole load of crap in it
    unlike
    posix socket() which returns an int. So maybe in win32 it does make sense.


    Well, it creates a socket. Why go through all of that logic when the
    socket is in a state that allows for reuse anyway?

    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Chris M. Thomasson@3:633/10 to All on Sun Jul 12 11:19:10 2026
    On 7/9/2026 8:58 PM, Bonita Montero wrote:
    Am 09.07.2026 um 22:01 schrieb Chris M. Thomasson:
    On 7/9/2026 1:34 AM, Bonita Montero wrote:
    Am 08.07.2026 um 23:32 schrieb Chris M. Thomasson:

    Not sure if a processor group can work with the power management or
    not. I think it can.

    OMG, what a nonsense.

    Not sure what MS means wrt:

    https://windowsreport.com/windows-11-hidden-cpu-setting-unlocks-
    advanced-performance-and-power-controls/

    https://learn.microsoft.com/en-us/windows/win32/procthread/cpu-sets

    "CPU Sets provide APIs to declare application affinity in a 'soft'
    manner that is compatible with OS power management. "

    CPU-affinities are a different topic.


    I can be the only way Windows can have power management wrt not wanting
    a certain cpu set to get hot. Or a gpu set... Heck the TDS! Iirc, the
    timeout on windows that can terminate a compute shader before its done computing!

    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Chris M. Thomasson@3:633/10 to All on Sun Jul 12 11:21:52 2026
    On 7/12/2026 8:18 AM, boltar@caprica.universe wrote:
    On Sat, 11 Jul 2026 14:10:20 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/11/2026 2:32 AM, boltar@caprica.universe wrote:
    On Fri, 10 Jul 2026 15:36:42 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/10/2026 2:25 AM, boltar@caprica.universe wrote:
    On Fri, 10 Jul 2026 00:16:41 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/5/2026 8:49 AM, boltar@caprica.universe wrote:
    Why? Once its down a socket - in unix - is just an integer
    pointing to nothing.
    What difference does it make if the same value gets reused?


    TF_REUSE_SOCKET allows one to reuse a socket in a more efficient
    way. DisconnectEx. Fairly nice! Avoid calling WSASocket again.

    Sounds like win32 is a whole other world. Thank god I never had to
    both with it.


    Fair enough. Reusing a socket is nothing new, right?

    On *nix a socket is simply a integer key into the lower level networking >>> subsystem. Re-using once the link it was the key for has been closed
    makes no sense. You may well get the same integer value if you close
    a socket then
    open a new one but its irrelevant.


    Reusing a socket make a heck of a lot of sense indeed!

    Maybe in Win32. On *nix its not only pointless, its meaningless. Sockets don't exist in any sense other than being an id for a connection. I suppose
    a hacker might like to close a connection in a hacked library , re-open
    a new one to their server and present the same socket id to the user application
    but I can't think of any other "use".


    I any system. Socket reuse is ideal. Why make a new one?

    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Chris M. Thomasson@3:633/10 to All on Sun Jul 12 11:22:50 2026
    On 7/5/2026 8:50 AM, boltar@caprica.universe wrote:
    On Sun, 05 Jul 2026 14:39:45 GMT
    scott@slp53.sl.home (Scott Lurndal) gabbled:
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> writes:
    On 7/5/2026 1:21 AM, boltar@caprica.universe wrote:

    I'm not interesting in win32, I only do posix and in posix a socket is >>>> simply
    an (indirect) integer index into a kernel network connection. Re-using >>>> one after

    the network connection has been closed makes no sense.


    Why? TF_REUSE_SOCKET is VERY useful.

    Posix has SO_REUSEADDR and SO_REUSEPORT for socket reuse.

    Thats not socket re-use, thats allowing a new listen socket to connect to the same interface address and port number before the previous one has been completely torn down.


    Socket reuse. Easy, let use it again for an AcceptEx, or a ConnectEx. Or closesocket and let it die.

    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Michael S@3:633/10 to All on Sun Jul 12 23:05:49 2026
    On Sun, 12 Jul 2026 15:19:52 -0000 (UTC)
    boltar@caprica.universe wrote:

    On Sat, 11 Jul 2026 14:11:15 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/11/2026 2:32 AM, boltar@caprica.universe wrote:
    On Fri, 10 Jul 2026 15:36:42 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/10/2026 2:25 AM, boltar@caprica.universe wrote:
    On Fri, 10 Jul 2026 00:16:41 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/5/2026 8:49 AM, boltar@caprica.universe wrote:
    Why? Once its down a socket - in unix - is just an integer
    pointing to nothing.
    What difference does it make if the same value gets reused?


    TF_REUSE_SOCKET allows one to reuse a socket in a more
    efficient way. DisconnectEx. Fairly nice! Avoid calling
    WSASocket again.

    Sounds like win32 is a whole other world. Thank god I never had
    to both with it.


    Fair enough. Reusing a socket is nothing new, right?

    On *nix a socket is simply a integer key into the lower level
    networking subsystem. Re-using once the link it was the key for
    has been closed makes no sense. You may well get the same integer
    value if you close a socket then
    open a new one but its irrelevant.


    After a DisconnctEx returns successfully, the socket in question can
    be reused for AcceptEx or ConnectEx. No need to call WSASocket to
    make a new one.

    Seems WSASocket() returns a structure with a whole load of crap in it
    unlike posix socket() which returns an int. So maybe in win32 it does
    make sense.


    WSASocket() return handle, which is pointer-sized.
    Exactly the same as socket() in that regard.

    BTW, WSASocket() is a specialised function that is used rather rarely.
    I had never seen it used.
    Supposedly, it was more useful back when IP networking was less
    dominant.










    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From boltar@3:633/10 to All on Mon Jul 13 09:39:56 2026
    On Sun, 12 Jul 2026 10:58:55 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/12/2026 8:15 AM, boltar@caprica.universe wrote:
    On Sat, 11 Jul 2026 14:09:51 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    [...]
    Ease is relative. Hard for you perhaps?

    Yes, its relative to creating a thread then detaching. 2 lines of C++, not >> much more in C. So, as I keep asking, show us your "simple" pool code.


    I don't work for you. I already showed you a little thread pool using my >experimental lock-free stack, you mocked it. I am working on some other >things right now. Fwiw, check this shit out:

    I didn't mock it, it simply wasn't an example of thread pool code any more
    than just giving the source to the linux kernel would be.

    https://skfb.ly/pyP9E

    https://skfb.ly/pyXH6

    https://skfb.ly/pzTEC

    Can your system view these?

    Once, then cloudfront gave up. Anyway, very impressive but I'm not interested in webassembly.


    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From boltar@3:633/10 to All on Mon Jul 13 09:42:19 2026
    On Sun, 12 Jul 2026 11:02:53 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/12/2026 8:19 AM, boltar@caprica.universe wrote:
    On Sat, 11 Jul 2026 14:11:15 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/11/2026 2:32 AM, boltar@caprica.universe wrote:
    On Fri, 10 Jul 2026 15:36:42 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/10/2026 2:25 AM, boltar@caprica.universe wrote:
    On Fri, 10 Jul 2026 00:16:41 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/5/2026 8:49 AM, boltar@caprica.universe wrote:
    Why? Once its down a socket - in unix - is just an integer
    pointing to nothing.
    What difference does it make if the same value gets reused?


    TF_REUSE_SOCKET allows one to reuse a socket in a more efficient >>>>>>> way. DisconnectEx. Fairly nice! Avoid calling WSASocket again.

    Sounds like win32 is a whole other world. Thank god I never had to >>>>>> both with it.


    Fair enough. Reusing a socket is nothing new, right?

    On *nix a socket is simply a integer key into the lower level networking >>>> subsystem. Re-using once the link it was the key for has been closed
    makes no sense. You may well get the same integer value if you close
    a socket then
    open a new one but its irrelevant.


    After a DisconnctEx returns successfully, the socket in question can
    be reused for AcceptEx or ConnectEx. No need to call WSASocket to make
    a new one.

    Seems WSASocket() returns a structure with a whole load of crap in it
    unlike
    posix socket() which returns an int. So maybe in win32 it does make sense. >>

    Well, it creates a socket. Why go through all of that logic when the
    socket is in a state that allows for reuse anyway?

    I guess it depends on how its implemented internally. It would seem to me that the vast majority of the time and effort by the kernel in any OS is setting
    up and tearing down connections, creating a structure in userspace is
    probably a fraction of that and plus userspace structures would require
    field validity checks each time its used whereis with an int its either valid or it isn't.


    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From boltar@3:633/10 to All on Mon Jul 13 10:26:21 2026
    On Sun, 12 Jul 2026 11:21:52 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/12/2026 8:18 AM, boltar@caprica.universe wrote:
    On Sat, 11 Jul 2026 14:10:20 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/11/2026 2:32 AM, boltar@caprica.universe wrote:
    On Fri, 10 Jul 2026 15:36:42 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/10/2026 2:25 AM, boltar@caprica.universe wrote:
    On Fri, 10 Jul 2026 00:16:41 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/5/2026 8:49 AM, boltar@caprica.universe wrote:
    Why? Once its down a socket - in unix - is just an integer
    pointing to nothing.
    What difference does it make if the same value gets reused?


    TF_REUSE_SOCKET allows one to reuse a socket in a more efficient >>>>>>> way. DisconnectEx. Fairly nice! Avoid calling WSASocket again.

    Sounds like win32 is a whole other world. Thank god I never had to >>>>>> both with it.


    Fair enough. Reusing a socket is nothing new, right?

    On *nix a socket is simply a integer key into the lower level networking >>>> subsystem. Re-using once the link it was the key for has been closed
    makes no sense. You may well get the same integer value if you close
    a socket then
    open a new one but its irrelevant.


    Reusing a socket make a heck of a lot of sense indeed!

    Maybe in Win32. On *nix its not only pointless, its meaningless. Sockets
    don't exist in any sense other than being an id for a connection. I suppose >> a hacker might like to close a connection in a hacked library , re-open
    a new one to their server and present the same socket id to the user
    application
    but I can't think of any other "use".


    I any system. Socket reuse is ideal. Why make a new one?

    Its just a data structure. At best all you're save is a single memory allocation.


    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Chris M. Thomasson@3:633/10 to All on Mon Jul 13 13:05:23 2026
    On 7/13/2026 3:26 AM, boltar@caprica.universe wrote:
    On Sun, 12 Jul 2026 11:21:52 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/12/2026 8:18 AM, boltar@caprica.universe wrote:
    On Sat, 11 Jul 2026 14:10:20 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/11/2026 2:32 AM, boltar@caprica.universe wrote:
    On Fri, 10 Jul 2026 15:36:42 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/10/2026 2:25 AM, boltar@caprica.universe wrote:
    On Fri, 10 Jul 2026 00:16:41 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/5/2026 8:49 AM, boltar@caprica.universe wrote:
    Why? Once its down a socket - in unix - is just an integer
    pointing to nothing.
    What difference does it make if the same value gets reused?


    TF_REUSE_SOCKET allows one to reuse a socket in a more efficient >>>>>>>> way. DisconnectEx. Fairly nice! Avoid calling WSASocket again.

    Sounds like win32 is a whole other world. Thank god I never had >>>>>>> to both with it.


    Fair enough. Reusing a socket is nothing new, right?

    On *nix a socket is simply a integer key into the lower level
    networking
    subsystem. Re-using once the link it was the key for has been
    closed makes no sense. You may well get the same integer value if
    you close a socket then
    open a new one but its irrelevant.


    Reusing a socket make a heck of a lot of sense indeed!

    Maybe in Win32. On *nix its not only pointless, its meaningless. Sockets >>> don't exist in any sense other than being an id for a connection. I
    suppose
    a hacker might like to close a connection in a hacked library , re-
    open a new one to their server and present the same socket id to the
    user application
    but I can't think of any other "use".


    I any system. Socket reuse is ideal. Why make a new one?

    Its just a data structure. At best all you're save is a single memory allocation.


    Its more than just a data structure. WSASocket needs to set it up. Init
    it. Saving that is a good thing.

    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Chris M. Thomasson@3:633/10 to All on Mon Jul 13 13:08:24 2026
    On 7/12/2026 1:05 PM, Michael S wrote:
    On Sun, 12 Jul 2026 15:19:52 -0000 (UTC)
    boltar@caprica.universe wrote:

    On Sat, 11 Jul 2026 14:11:15 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/11/2026 2:32 AM, boltar@caprica.universe wrote:
    On Fri, 10 Jul 2026 15:36:42 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/10/2026 2:25 AM, boltar@caprica.universe wrote:
    On Fri, 10 Jul 2026 00:16:41 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/5/2026 8:49 AM, boltar@caprica.universe wrote:
    Why? Once its down a socket - in unix - is just an integer
    pointing to nothing.
    What difference does it make if the same value gets reused?


    TF_REUSE_SOCKET allows one to reuse a socket in a more
    efficient way. DisconnectEx. Fairly nice! Avoid calling
    WSASocket again.

    Sounds like win32 is a whole other world. Thank god I never had
    to both with it.


    Fair enough. Reusing a socket is nothing new, right?

    On *nix a socket is simply a integer key into the lower level
    networking subsystem. Re-using once the link it was the key for
    has been closed makes no sense. You may well get the same integer
    value if you close a socket then
    open a new one but its irrelevant.


    After a DisconnctEx returns successfully, the socket in question can
    be reused for AcceptEx or ConnectEx. No need to call WSASocket to
    make a new one.

    Seems WSASocket() returns a structure with a whole load of crap in it
    unlike posix socket() which returns an int. So maybe in win32 it does
    make sense.


    WSASocket() return handle, which is pointer-sized.
    Exactly the same as socket() in that regard.

    BTW, WSASocket() is a specialised function that is used rather rarely.
    I had never seen it used.
    Supposedly, it was more useful back when IP networking was less
    dominant.

    WSASocket is more fine grain than socket. Also, its needed for
    overlapped io on the windozer:

    int
    create_accept(
    per_socket& listen_sock, // also renamed for consistency
    per_socket& accept_sock, // <--- demon slain
    per_io& pio
    ) {
    accept_sock.m_raw.m_socket = WSASocket(
    AF_INET, SOCK_STREAM, IPPROTO_TCP,
    nullptr, 0, WSA_FLAG_OVERLAPPED
    );

    if (accept_sock.m_raw.m_socket == INVALID_SOCKET)
    {
    std::cout << "create_accept WSASocket() failed: "
    << WSAGetLastError() << "\n";
    return 1;
    }

    std::cout << "accept_socket = " << accept_sock.m_raw.m_socket << "\n";

    pio.m_raw.m_buf = accept_sock.m_raw.m_buf;
    pio.m_raw.m_buf_n = accept_sock.m_raw.m_buf_n;

    pio.m_raw.m_per_socket = &accept_sock;
    pio.m_raw.m_state |= CT_PER_IO_STATE_ACCEPT;

    DWORD bytes_received = 0;

    BOOL ok = m_winsock.m_wsaex.m_acceptex(
    listen_sock.m_raw.m_socket,
    accept_sock.m_raw.m_socket,
    pio.m_raw.m_buf,
    0,
    sizeof(SOCKADDR_IN) + 16,
    sizeof(SOCKADDR_IN) + 16,
    &bytes_received,
    &pio.m_raw.m_ol
    );

    if (!ok && WSAGetLastError() != ERROR_IO_PENDING)
    {
    std::cout << "AcceptEx failed: " <<
    WSAGetLastError() << "\n";
    return 1;
    }

    std::cout << "AcceptEx posted!\n";
    return 0;
    }

    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Chris M. Thomasson@3:633/10 to All on Mon Jul 13 13:12:32 2026
    On 7/12/2026 8:23 AM, boltar@caprica.universe wrote:
    On Sat, 11 Jul 2026 14:41:04 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/11/2026 2:28 AM, boltar@caprica.universe wrote:
    On Fri, 10 Jul 2026 19:13:06 +0300
    Having a window deal with data just seems a moronic paradigm to me -
    what if
    more than 1 window needs it or the main core application? Ridiculous.


    Create two windows that use the same core app/data?

    I meant who gets the data first and what if the logic in one "window" conflicts with another. What a mess.

    Not sure what you mean. One window can show lets say, real time stats.
    The other one can render real time using the GPU. Why should say, FPS be
    100% accurate anyway?


    Just have some graphic objects and a
    couple of core threads, one deals with graphics events and callbacks,
    the other does everything else. At least thats how graphical
    applications are written on sane OS's, not some toy that evolved from a
    disk monitor.


    Have you ever used imgui? Its pretty nice.

    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Chris M. Thomasson@3:633/10 to All on Mon Jul 13 13:14:29 2026
    On 7/13/2026 2:39 AM, boltar@caprica.universe wrote:
    On Sun, 12 Jul 2026 10:58:55 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/12/2026 8:15 AM, boltar@caprica.universe wrote:
    On Sat, 11 Jul 2026 14:09:51 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    [...]
    Ease is relative. Hard for you perhaps?

    Yes, its relative to creating a thread then detaching. 2 lines of C+
    +, not
    much more in C. So, as I keep asking, show us your "simple" pool code.


    I don't work for you. I already showed you a little thread pool using
    my experimental lock-free stack, you mocked it. I am working on some
    other things right now. Fwiw, check this shit out:

    I didn't mock it, it simply wasn't an example of thread pool code any more than just giving the source to the linux kernel would be.

    https://skfb.ly/pyP9E

    https://skfb.ly/pyXH6

    https://skfb.ly/pzTEC

    Can your system view these?

    Once, then cloudfront gave up. Anyway, very impressive but I'm not interested
    in webassembly.


    Oh. I meant my models. Btw, afaict the site uses WebGL.

    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From boltar@3:633/10 to All on Tue Jul 14 10:58:16 2026
    On Mon, 13 Jul 2026 13:05:23 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/13/2026 3:26 AM, boltar@caprica.universe wrote:
    Its just a data structure. At best all you're save is a single memory
    allocation.


    Its more than just a data structure. WSASocket needs to set it up. Init
    it. Saving that is a good thing.

    And it'll need to set it up again for a new connection unless its identical
    to the previous one which is unlikely but then it would still have to check
    the values to find out and update them if wrong, hardly efficient. Hence all its rarely saving is a malloc() of a blank socket structure, the cost of which in the process of setting up a network connection, particularly TCP, is statistical noise.


    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From boltar@3:633/10 to All on Tue Jul 14 11:05:28 2026
    On Mon, 13 Jul 2026 13:12:32 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/12/2026 8:23 AM, boltar@caprica.universe wrote:
    On Sat, 11 Jul 2026 14:41:04 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/11/2026 2:28 AM, boltar@caprica.universe wrote:
    On Fri, 10 Jul 2026 19:13:06 +0300
    Having a window deal with data just seems a moronic paradigm to me -
    what if
    more than 1 window needs it or the main core application? Ridiculous.


    Create two windows that use the same core app/data?

    I meant who gets the data first and what if the logic in one "window"
    conflicts with another. What a mess.

    Not sure what you mean. One window can show lets say, real time stats.
    The other one can render real time using the GPU. Why should say, FPS be >100% accurate anyway?

    I'm not going to second guess how people write apps, but I'm sure there are plenty where 2 or more windows require the same data. Why would you "send"
    data to each window instead of just having a central store which is then
    picked up by the window draw functions and displayed appropriately.

    Just have some graphic objects and a
    couple of core threads, one deals with graphics events and callbacks,
    the other does everything else. At least thats how graphical
    applications are written on sane OS's, not some toy that evolved from a
    disk monitor.


    Have you ever used imgui? Its pretty nice.

    Never heard of it. Looks quite nice. Had a poke around the code and all the
    cpp files I looked at seemed to be plain C. I can understand using C for library interfacing but inside the app core it seems a strange choice
    unless he's going for max portability, but when why not name the files .c? Naming them .cpp may confuse some IDEs and even compilers.


    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Scott Lurndal@3:633/10 to All on Tue Jul 14 14:31:52 2026
    boltar@caprica.universe writes:
    On Mon, 13 Jul 2026 13:12:32 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/12/2026 8:23 AM, boltar@caprica.universe wrote:
    On Sat, 11 Jul 2026 14:41:04 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/11/2026 2:28 AM, boltar@caprica.universe wrote:
    On Fri, 10 Jul 2026 19:13:06 +0300
    Having a window deal with data just seems a moronic paradigm to me - >>>>> what if
    more than 1 window needs it or the main core application? Ridiculous. >>>>>

    Create two windows that use the same core app/data?

    I meant who gets the data first and what if the logic in one "window"
    conflicts with another. What a mess.

    Not sure what you mean. One window can show lets say, real time stats.
    The other one can render real time using the GPU. Why should say, FPS be >>100% accurate anyway?

    I'm not going to second guess how people write apps, but I'm sure there are >plenty where 2 or more windows require the same data. Why would you "send" >data to each window instead of just having a central store which is then >picked up by the window draw functions and displayed appropriately.

    Typical patterns for GUI applications often follow the smalltalk
    pattern Model-View-Controller.

    https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller

    Just have some graphic objects and a
    couple of core threads, one deals with graphics events and callbacks,
    the other does everything else. At least thats how graphical
    applications are written on sane OS's, not some toy that evolved from a >>> disk monitor.


    Have you ever used imgui? Its pretty nice.

    Never heard of it. Looks quite nice. Had a poke around the code and all the >cpp files I looked at seemed to be plain C. I can understand using C for >library interfacing but inside the app core it seems a strange choice
    unless he's going for max portability, but when why not name the files .c? >Naming them .cpp may confuse some IDEs and even compilers.


    The .cpp and .h files I looked at were actual C++ (using namespaces).

    Although one wonders why the author felt it necessary
    to disable all the useful compiler warnings for GCC and clang
    in demo.cpp.


    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From boltar@3:633/10 to All on Tue Jul 14 15:42:04 2026
    On Tue, 14 Jul 2026 14:31:52 GMT
    scott@slp53.sl.home (Scott Lurndal) gabbled:
    boltar@caprica.universe writes:
    On Mon, 13 Jul 2026 13:12:32 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/12/2026 8:23 AM, boltar@caprica.universe wrote:
    On Sat, 11 Jul 2026 14:41:04 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/11/2026 2:28 AM, boltar@caprica.universe wrote:
    On Fri, 10 Jul 2026 19:13:06 +0300
    Having a window deal with data just seems a moronic paradigm to me - >>>>>> what if
    more than 1 window needs it or the main core application? Ridiculous. >>>>>>

    Create two windows that use the same core app/data?

    I meant who gets the data first and what if the logic in one "window"
    conflicts with another. What a mess.

    Not sure what you mean. One window can show lets say, real time stats. >>>The other one can render real time using the GPU. Why should say, FPS be >>>100% accurate anyway?

    I'm not going to second guess how people write apps, but I'm sure there are >>plenty where 2 or more windows require the same data. Why would you "send" >>data to each window instead of just having a central store which is then >>picked up by the window draw functions and displayed appropriately.

    Typical patterns for GUI applications often follow the smalltalk
    pattern Model-View-Controller.

    Fair enough. Smalltalk certainly had many qualities, but efficiency wasn't
    one of them.


    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Chris M. Thomasson@3:633/10 to All on Tue Jul 14 13:45:36 2026
    On 7/14/2026 3:58 AM, boltar@caprica.universe wrote:
    On Mon, 13 Jul 2026 13:05:23 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/13/2026 3:26 AM, boltar@caprica.universe wrote:
    Its just a data structure. At best all you're save is a single memory
    allocation.


    Its more than just a data structure. WSASocket needs to set it up.
    Init it. Saving that is a good thing.

    And it'll need to set it up again for a new connection unless its identical to the previous one which is unlikely but then it would still have to check the values to find out and update them if wrong, hardly efficient.

    Huh? It saves a lot of work wrt closesocket, and calling WSASocket
    again. Why not reuse the existing structure brought back into a certian
    state such that it can be used with AcceptEx or ConnectEx again and
    totally avoid calling WSASocket...



    Hence
    all its rarely saving is a malloc() of a blank socket structure, the
    cost of which
    in the process of setting up a network connection, particularly TCP, is statistical noise.


    No. Its more than that.

    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From boltar@3:633/10 to All on Wed Jul 15 11:23:35 2026
    On Tue, 14 Jul 2026 13:45:36 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/14/2026 3:58 AM, boltar@caprica.universe wrote:
    On Mon, 13 Jul 2026 13:05:23 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/13/2026 3:26 AM, boltar@caprica.universe wrote:
    Its just a data structure. At best all you're save is a single memory >>>> allocation.


    Its more than just a data structure. WSASocket needs to set it up.
    Init it. Saving that is a good thing.

    And it'll need to set it up again for a new connection unless its identical >> to the previous one which is unlikely but then it would still have to check >> the values to find out and update them if wrong, hardly efficient.

    Huh? It saves a lot of work wrt closesocket, and calling WSASocket

    I have no idea what "work" windows does with sockets but as I've said more
    than once, on unix a socket is just an id number used to link userspace to
    the kernel network subsystem. Once the network connection is closed or put into
    TIME_WAIT all you're left with is a useless integer hence re-use is irrelevant and in fact there's every chance it'll be re-issued for another socket, pipe, file whatever very soon.

    again. Why not reuse the existing structure brought back into a certian >state such that it can be used with AcceptEx or ConnectEx again and
    totally avoid calling WSASocket...

    Sounds like a lot of userspace nonsense that is specific to win32.


    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Scott Lurndal@3:633/10 to All on Wed Jul 15 14:07:58 2026
    boltar@caprica.universe writes:
    On Tue, 14 Jul 2026 13:45:36 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:

    Huh? It saves a lot of work wrt closesocket, and calling WSASocket

    I have no idea what "work" windows does with sockets but as I've said more >than once, on unix a socket is just an id number used to link userspace to

    Specifically, the socket(2) system call returns a standard file descriptor
    that can be used with the other file-related system calls such as read,
    write, poll/select, ioctl, etc.


    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From boltar@3:633/10 to All on Wed Jul 15 15:54:21 2026
    On Wed, 15 Jul 2026 14:07:58 GMT
    scott@slp53.sl.home (Scott Lurndal) gabbled:
    boltar@caprica.universe writes:
    On Tue, 14 Jul 2026 13:45:36 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:

    Huh? It saves a lot of work wrt closesocket, and calling WSASocket

    I have no idea what "work" windows does with sockets but as I've said more >>than once, on unix a socket is just an id number used to link userspace to

    Specifically, the socket(2) system call returns a standard file descriptor >that can be used with the other file-related system calls such as read, >write, poll/select, ioctl, etc.

    Indeed. Windows OTOH appears to have a specific C struct for sockets which seems
    unnecessarily complicated.


    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Chris M. Thomasson@3:633/10 to All on Wed Jul 15 15:51:10 2026
    On 7/15/2026 8:54 AM, boltar@caprica.universe wrote:
    On Wed, 15 Jul 2026 14:07:58 GMT
    scott@slp53.sl.home (Scott Lurndal) gabbled:
    boltar@caprica.universe writes:
    On Tue, 14 Jul 2026 13:45:36 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:

    Huh? It saves a lot of work wrt closesocket, and calling WSASocket

    I have no idea what "work" windows does with sockets but as I've said more >>> than once, on unix a socket is just an id number used to link userspace to >>
    Specifically, the socket(2) system call returns a standard file descriptor >> that can be used with the other file-related system calls such as read,
    write, poll/select, ioctl, etc.

    Indeed. Windows OTOH appears to have a specific C struct for sockets which seems
    unnecessarily complicated.


    Avoiding another call to WSASocket is beneficial.

    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From boltar@3:633/10 to All on Thu Jul 16 10:44:07 2026
    On Wed, 15 Jul 2026 15:51:10 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/15/2026 8:54 AM, boltar@caprica.universe wrote:
    On Wed, 15 Jul 2026 14:07:58 GMT
    scott@slp53.sl.home (Scott Lurndal) gabbled:
    boltar@caprica.universe writes:
    On Tue, 14 Jul 2026 13:45:36 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:

    Huh? It saves a lot of work wrt closesocket, and calling WSASocket

    I have no idea what "work" windows does with sockets but as I've said more >>>> than once, on unix a socket is just an id number used to link userspace to >>>
    Specifically, the socket(2) system call returns a standard file descriptor >>> that can be used with the other file-related system calls such as read,
    write, poll/select, ioctl, etc.

    Indeed. Windows OTOH appears to have a specific C struct for sockets which >seems
    unnecessarily complicated.


    Avoiding another call to WSASocket is beneficial.

    If windows didn't have a userspace struct representing a socket it wouldn't
    be needed in the first place.


    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Chris M. Thomasson@3:633/10 to All on Thu Jul 16 12:37:20 2026
    On 7/16/2026 3:44 AM, boltar@caprica.universe wrote:
    On Wed, 15 Jul 2026 15:51:10 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/15/2026 8:54 AM, boltar@caprica.universe wrote:
    On Wed, 15 Jul 2026 14:07:58 GMT
    scott@slp53.sl.home (Scott Lurndal) gabbled:
    boltar@caprica.universe writes:
    On Tue, 14 Jul 2026 13:45:36 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:

    Huh? It saves a lot of work wrt closesocket, and calling WSASocket

    I have no idea what "work" windows does with sockets but as I've
    said more
    than once, on unix a socket is just an id number used to link
    userspace to

    Specifically, the socket(2) system call returns a standard file
    descriptor
    that can be used with the other file-related system calls such as read, >>>> write, poll/select, ioctl, etc.

    Indeed. Windows OTOH appears to have a specific C struct for sockets
    which
    seems
    unnecessarily complicated.


    Avoiding another call to WSASocket is beneficial.

    If windows didn't have a userspace struct representing a socket it wouldn't be needed in the first place.


    I thought that Linux has a socket reuse thing as well? Anyway...

    You should tell MS that. I was lucky enough to be able to talk to some
    Windows kernel guys. Iirc, one of them was Neill Clift way back on comp.programming.threads.

    If I am on Windows I use IOCP and use all of it, all the bells ans
    whistles. If I am on Linux, I would use io_uring for SURE!


    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Chris M. Thomasson@3:633/10 to All on Thu Jul 16 12:40:42 2026
    On 7/16/2026 3:44 AM, boltar@caprica.universe wrote:
    On Wed, 15 Jul 2026 15:51:10 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/15/2026 8:54 AM, boltar@caprica.universe wrote:
    On Wed, 15 Jul 2026 14:07:58 GMT
    scott@slp53.sl.home (Scott Lurndal) gabbled:
    boltar@caprica.universe writes:
    On Tue, 14 Jul 2026 13:45:36 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:

    Huh? It saves a lot of work wrt closesocket, and calling WSASocket

    I have no idea what "work" windows does with sockets but as I've
    said more
    than once, on unix a socket is just an id number used to link
    userspace to

    Specifically, the socket(2) system call returns a standard file
    descriptor
    that can be used with the other file-related system calls such as read, >>>> write, poll/select, ioctl, etc.

    Indeed. Windows OTOH appears to have a specific C struct for sockets
    which
    seems
    unnecessarily complicated.


    Avoiding another call to WSASocket is beneficial.

    If windows didn't have a userspace struct representing a socket it wouldn't be needed in the first place.


    Why would you closesocket, when we can issue a DisconnectEx and once
    that per_io get completed in the io_worker thread pool, we can add the
    socket back to the per_socket pool(s), or just issue a new AcceptEx
    right there! No need to call closesocket, and then WSASocket again, right?

    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Chris M. Thomasson@3:633/10 to All on Thu Jul 16 13:50:00 2026
    On 7/13/2026 2:42 AM, boltar@caprica.universe wrote:
    On Sun, 12 Jul 2026 11:02:53 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/12/2026 8:19 AM, boltar@caprica.universe wrote:
    On Sat, 11 Jul 2026 14:11:15 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/11/2026 2:32 AM, boltar@caprica.universe wrote:
    On Fri, 10 Jul 2026 15:36:42 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/10/2026 2:25 AM, boltar@caprica.universe wrote:
    On Fri, 10 Jul 2026 00:16:41 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/5/2026 8:49 AM, boltar@caprica.universe wrote:
    Why? Once its down a socket - in unix - is just an integer
    pointing to nothing.
    What difference does it make if the same value gets reused?


    TF_REUSE_SOCKET allows one to reuse a socket in a more efficient >>>>>>>> way. DisconnectEx. Fairly nice! Avoid calling WSASocket again.

    Sounds like win32 is a whole other world. Thank god I never had >>>>>>> to both with it.


    Fair enough. Reusing a socket is nothing new, right?

    On *nix a socket is simply a integer key into the lower level
    networking
    subsystem. Re-using once the link it was the key for has been
    closed makes no sense. You may well get the same integer value if
    you close a socket then
    open a new one but its irrelevant.


    After a DisconnctEx returns successfully, the socket in question can
    be reused for AcceptEx or ConnectEx. No need to call WSASocket to
    make a new one.

    Seems WSASocket() returns a structure with a whole load of crap in it
    unlike
    posix socket() which returns an int. So maybe in win32 it does make
    sense.


    Well, it creates a socket. Why go through all of that logic when the
    socket is in a state that allows for reuse anyway?

    I guess it depends on how its implemented internally.

    Indeed it does. Its a kernel call, and does some things. Avoid calling closesocket and then socket again!

    Also, think of what can occur. Say we want a graceful shutdown. shutdown(SD_SEND), wait for a zero byte recv, or whatever. If we can
    reuse that socket for an accept or connect, well, GOOD! Why would I call closesocket on it when I don't have to. Actually, reusing sockets is
    part of POSIX with some flags. Perhaps not as fine grain as Windows, but whatever.

    It would seem to
    me that
    the vast majority of the time and effort by the kernel in any OS is setting up and tearing down connections, creating a structure in userspace is probably a fraction of that and plus userspace structures would require field validity checks each time its used whereis with an int its either valid or it isn't.


    Its more than that. It works with the kernel as well.

    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Chris M. Thomasson@3:633/10 to All on Thu Jul 16 13:56:11 2026
    On 7/13/2026 1:08 PM, Chris M. Thomasson wrote:
    [...]
    WSASocket is more fine grain than socket. Also, its needed for
    overlapped io on the windozer:

    int
    ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ create_accept(
    ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ per_socket& listen_sock,ÿÿÿÿÿ // also renamed for consistency
    ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ per_socket& accept_sock,ÿÿÿÿÿ // <--- demon slain
    ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ per_io& pio
    ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ) {
    ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ accept_sock.m_raw.m_socket = WSASocket(
    ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ AF_INET, SOCK_STREAM, IPPROTO_TCP,
    ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ nullptr, 0, WSA_FLAG_OVERLAPPED
    ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ );

    This is where I need to prime my per_socket pools with sockets! Instead
    of calling WSASocket here, create_accept can check a pool of them first.
    If that is empty, then we can create another one and handle the errors
    if that fails.




    ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ if (accept_sock.m_raw.m_socket == INVALID_SOCKET)
    ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ {
    ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ std::cout << "create_accept WSASocket() failed: "
    ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ << WSAGetLastError() << "\n";
    ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ return 1;
    ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ }

    ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ std::cout << "accept_socket = " << accept_sock.m_raw.m_socket << "\n";

    ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ pio.m_raw.m_buf = accept_sock.m_raw.m_buf;
    ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ pio.m_raw.m_buf_n = accept_sock.m_raw.m_buf_n;

    ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ pio.m_raw.m_per_socket = &accept_sock;
    ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ pio.m_raw.m_state |= CT_PER_IO_STATE_ACCEPT;

    ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ DWORD bytes_received = 0;

    ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ BOOL ok = m_winsock.m_wsaex.m_acceptex(
    ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ listen_sock.m_raw.m_socket,
    ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ accept_sock.m_raw.m_socket,
    ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ pio.m_raw.m_buf,
    ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ 0,
    ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ sizeof(SOCKADDR_IN) + 16,
    ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ sizeof(SOCKADDR_IN) + 16,
    ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ &bytes_received,
    ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ &pio.m_raw.m_ol
    ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ );

    ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ if (!ok && WSAGetLastError() != ERROR_IO_PENDING)
    ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ {
    ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ std::cout << "AcceptEx failed: " << WSAGetLastError() << "\n";
    ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ return 1;
    ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ }

    ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ std::cout << "AcceptEx posted!\n";
    ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ return 0;
    ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ }


    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Chris M. Thomasson@3:633/10 to All on Thu Jul 16 13:58:55 2026
    On 7/16/2026 1:56 PM, Chris M. Thomasson wrote:
    On 7/13/2026 1:08 PM, Chris M. Thomasson wrote:
    [...]
    WSASocket is more fine grain than socket. Also, its needed for
    overlapped io on the windozer:

    int
    ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ create_accept(
    ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ per_socket& listen_sock,ÿÿÿÿÿ // also renamed for
    consistency
    ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ per_socket& accept_sock,ÿÿÿÿÿ // <--- demon slain
    ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ per_io& pio
    ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ) {
    ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ accept_sock.m_raw.m_socket = WSASocket(
    ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ AF_INET, SOCK_STREAM, IPPROTO_TCP,
    ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ nullptr, 0, WSA_FLAG_OVERLAPPED
    ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ );

    This is where I need to prime my per_socket pools with sockets! Instead
    of calling WSASocket here, create_accept can check a pool of them first.
    If that is empty, then we can create another one and handle the errors
    if that fails.

    Well, that should be before create_accept anyway. accept_sock should
    already have a working accept_sock.m_raw.m_socket






    ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ if (accept_sock.m_raw.m_socket == INVALID_SOCKET)
    ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ {
    ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ std::cout << "create_accept WSASocket()
    failed: "
    ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ << WSAGetLastError() << "\n";
    ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ return 1;
    ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ }

    ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ std::cout << "accept_socket = " <<
    accept_sock.m_raw.m_socket << "\n";

    ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ pio.m_raw.m_buf = accept_sock.m_raw.m_buf;
    ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ pio.m_raw.m_buf_n = accept_sock.m_raw.m_buf_n;

    ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ pio.m_raw.m_per_socket = &accept_sock;
    ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ pio.m_raw.m_state |= CT_PER_IO_STATE_ACCEPT;

    ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ DWORD bytes_received = 0;

    ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ BOOL ok = m_winsock.m_wsaex.m_acceptex(
    ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ listen_sock.m_raw.m_socket,
    ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ accept_sock.m_raw.m_socket,
    ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ pio.m_raw.m_buf,
    ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ 0,
    ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ sizeof(SOCKADDR_IN) + 16,
    ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ sizeof(SOCKADDR_IN) + 16,
    ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ &bytes_received,
    ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ &pio.m_raw.m_ol
    ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ );

    ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ if (!ok && WSAGetLastError() != ERROR_IO_PENDING)
    ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ {
    ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ std::cout << "AcceptEx failed: " <<
    WSAGetLastError() << "\n";
    ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ return 1;
    ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ }

    ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ std::cout << "AcceptEx posted!\n";
    ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ return 0;
    ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ }



    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From boltar@3:633/10 to All on Fri Jul 17 09:26:19 2026
    On Thu, 16 Jul 2026 12:37:20 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/16/2026 3:44 AM, boltar@caprica.universe wrote:
    On Wed, 15 Jul 2026 15:51:10 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/15/2026 8:54 AM, boltar@caprica.universe wrote:
    On Wed, 15 Jul 2026 14:07:58 GMT
    scott@slp53.sl.home (Scott Lurndal) gabbled:
    boltar@caprica.universe writes:
    On Tue, 14 Jul 2026 13:45:36 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:

    Huh? It saves a lot of work wrt closesocket, and calling WSASocket >>>>>>
    I have no idea what "work" windows does with sockets but as I've
    said more
    than once, on unix a socket is just an id number used to link
    userspace to

    Specifically, the socket(2) system call returns a standard file
    descriptor
    that can be used with the other file-related system calls such as read, >>>>> write, poll/select, ioctl, etc.

    Indeed. Windows OTOH appears to have a specific C struct for sockets
    which
    seems
    unnecessarily complicated.


    Avoiding another call to WSASocket is beneficial.

    If windows didn't have a userspace struct representing a socket it wouldn't >> be needed in the first place.


    I thought that Linux has a socket reuse thing as well? Anyway...

    I've already explained that SO_REUSEADDR simply allows a new listen socket to listen on an interface+port combination while the previous listen socket is still in TIME_WAIT. It has nothing to do with re-using a socket.

    You should tell MS that. I was lucky enough to be able to talk to some >Windows kernel guys. Iirc, one of them was Neill Clift way back on >comp.programming.threads.

    If I am on Windows I use IOCP and use all of it, all the bells ans
    whistles. If I am on Linux, I would use io_uring for SURE!

    Which has nothing to do with re-using sockets.



    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From boltar@3:633/10 to All on Fri Jul 17 09:27:03 2026
    On Thu, 16 Jul 2026 12:40:42 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/16/2026 3:44 AM, boltar@caprica.universe wrote:
    On Wed, 15 Jul 2026 15:51:10 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/15/2026 8:54 AM, boltar@caprica.universe wrote:
    On Wed, 15 Jul 2026 14:07:58 GMT
    scott@slp53.sl.home (Scott Lurndal) gabbled:
    boltar@caprica.universe writes:
    On Tue, 14 Jul 2026 13:45:36 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:

    Huh? It saves a lot of work wrt closesocket, and calling WSASocket >>>>>>
    I have no idea what "work" windows does with sockets but as I've
    said more
    than once, on unix a socket is just an id number used to link
    userspace to

    Specifically, the socket(2) system call returns a standard file
    descriptor
    that can be used with the other file-related system calls such as read, >>>>> write, poll/select, ioctl, etc.

    Indeed. Windows OTOH appears to have a specific C struct for sockets
    which
    seems
    unnecessarily complicated.


    Avoiding another call to WSASocket is beneficial.

    If windows didn't have a userspace struct representing a socket it wouldn't >> be needed in the first place.


    Why would you closesocket, when we can issue a DisconnectEx and once
    that per_io get completed in the io_worker thread pool, we can add the >socket back to the per_socket pool(s), or just issue a new AcceptEx
    right there! No need to call closesocket, and then WSASocket again, right?

    No idea, I'm not a win32 developer. Windows seems to make a complete meal
    out of what should be - in userspace - a simple process.


    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Michael S@3:633/10 to All on Fri Jul 17 13:32:09 2026
    On Thu, 16 Jul 2026 12:37:20 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> wrote:

    If I am on Windows I use IOCP and use all of it, all the bells ans
    whistles. If I am on Linux, I would use io_uring for SURE!


    Hopefully after that you measure performance, discover that it's either
    exactly the same speed as simple code or, more likely, slower and then
    you throw complicated crap into trash can, where it belongs.
    Well, probably I am hoping for too much.





    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Wuns Haerst@3:633/10 to All on Fri Jul 17 13:45:09 2026
    Am 30.06.2026 um 10:27 schrieb Wuns Haerst:
    I measured the time it takes to create a thread on both Windows and
    Linux. On Windows, it takes around 120,000 clock cycles, whereas on
    Linux, it takes about a third of that.
    It occurred to me that one could simply inline the thread's main
    function. This would eliminate the need for the operating system
    call to create the thread. In this scenario, the compiler ? or its
    runtime ? would have to handle the scheduling.
    I estimate that this would reduce the thread creation overhead to
    just a few clock cycles, making thread pools unnecessary. I?m just
    not sure yet exactly how to go about implementing this. Perhaps
    someone here can help me with it.
    Please send any relevant suggestions via email only, as I intend
    to patent this idea once it is fully developed.

    I found a way to handle that: I've implemented a green thread API and
    the scheduler is a generic component which takes a function object as
    a template parameter. With that I easily can integrate threads inlined.
    For some benchmarks with small threaded tasks this gives a hughe per-
    formance advantage. Strike !

    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Bonita Montero@3:633/10 to All on Fri Jul 17 13:56:23 2026
    Am 06.07.2026 um 19:47 schrieb Scott Lurndal:

    You can limit a process to a set of cores, or an individual core
    with taskset and/or numactl. These have been available since the
    early 2000's. Combine that with setrlimit(2) and you have failry
    fined grained control of both core assignment and utilization.

    With setrlimit() it's not possible what I've mentioned. Or show me
    how to reduce the CPU-time consumed by a thread or a thread group
    over a time interval. That's only possible with control groups on
    current Linuxes.


    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Michael S@3:633/10 to All on Fri Jul 17 15:23:27 2026
    On Fri, 17 Jul 2026 13:45:09 +0200
    Wuns Haerst <Wuns.Haerst@wurstfabrik.at> wrote:

    Am 30.06.2026 um 10:27 schrieb Wuns Haerst:
    I measured the time it takes to create a thread on both Windows and
    Linux. On Windows, it takes around 120,000 clock cycles, whereas on
    Linux, it takes about a third of that.
    It occurred to me that one could simply inline the thread's main
    function. This would eliminate the need for the operating system
    call to create the thread. In this scenario, the compiler ? or
    its
    runtime ? would have to handle the scheduling.
    I estimate that this would reduce the thread creation overhead to
    just a few clock cycles, making thread pools unnecessary. I?m j
    ust
    not sure yet exactly how to go about implementing this. Perhaps
    someone here can help me with it.
    Please send any relevant suggestions via email only, as I intend
    to patent this idea once it is fully developed.

    I found a way to handle that: I've implemented a green thread API and
    the scheduler is a generic component which takes a function object as
    a template parameter. With that I easily can integrate threads
    inlined. For some benchmarks with small threaded tasks this gives a
    hughe per- formance advantage. Strike !

    If it helps, it's a sure sign that the job would be better done
    non-threaded. Did you consider state machine?


    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Chris M. Thomasson@3:633/10 to All on Fri Jul 17 12:00:55 2026
    On 7/17/2026 3:32 AM, Michael S wrote:
    On Thu, 16 Jul 2026 12:37:20 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> wrote:

    If I am on Windows I use IOCP and use all of it, all the bells ans
    whistles. If I am on Linux, I would use io_uring for SURE!


    Hopefully after that you measure performance, discover that it's either exactly the same speed as simple code or, more likely, slower and then
    you throw complicated crap into trash can, where it belongs.
    Well, probably I am hoping for too much.

    Well, when in Rome? IOCP on Windows is the way to write a server, or a
    client for that matter. On my free time I am slowly but surely
    recreating my old proxy server code from around 2002. So far mostly from memory. Some of the API's are messing me up a little. Hard to remember them.

    On Linux AIO or io_uring. The fun part is that they have very similar
    logic to IOCP.

    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Michael S@3:633/10 to All on Sat Jul 18 23:12:08 2026
    On Fri, 17 Jul 2026 12:00:55 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> wrote:

    On 7/17/2026 3:32 AM, Michael S wrote:
    On Thu, 16 Jul 2026 12:37:20 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> wrote:

    If I am on Windows I use IOCP and use all of it, all the bells ans
    whistles. If I am on Linux, I would use io_uring for SURE!



    Well, when in Rome? IOCP on Windows is the way to write a server, or
    a client for that matter. On my free time I am slowly but surely
    recreating my old proxy server code from around 2002. So far mostly
    from memory. Some of the API's are messing me up a little. Hard to
    remember them.

    On Linux AIO or io_uring. The fun part is that they have very similar
    logic to IOCP.


    So you never measure if complicated code is faster than the simple one
    or not.
    Somehow, it's what I expected.



    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Chris M. Thomasson@3:633/10 to All on Sat Jul 18 17:15:28 2026
    On 7/18/2026 1:12 PM, Michael S wrote:
    On Fri, 17 Jul 2026 12:00:55 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> wrote:

    On 7/17/2026 3:32 AM, Michael S wrote:
    On Thu, 16 Jul 2026 12:37:20 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> wrote:

    If I am on Windows I use IOCP and use all of it, all the bells ans
    whistles. If I am on Linux, I would use io_uring for SURE!



    Well, when in Rome? IOCP on Windows is the way to write a server, or
    a client for that matter. On my free time I am slowly but surely
    recreating my old proxy server code from around 2002. So far mostly
    from memory. Some of the API's are messing me up a little. Hard to
    remember them.

    On Linux AIO or io_uring. The fun part is that they have very similar
    logic to IOCP.


    So you never measure if complicated code is faster than the simple one
    or not.
    Somehow, it's what I expected.



    Why do you assume that? IOCP is WAY more efficient than using say,
    select, or the event based thing using WaitForMultipleObjects. AIO or
    io_uring is way more efficient than using select, even epoll iirc.

    If you are building a robust server that is meant to scale up, we need
    these API's.

    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Chris M. Thomasson@3:633/10 to All on Sat Jul 18 17:18:48 2026
    On 7/18/2026 5:15 PM, Chris M. Thomasson wrote:
    On 7/18/2026 1:12 PM, Michael S wrote:
    On Fri, 17 Jul 2026 12:00:55 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> wrote:

    On 7/17/2026 3:32 AM, Michael S wrote:
    On Thu, 16 Jul 2026 12:37:20 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> wrote:

    If I am on Windows I use IOCP and use all of it, all the bells ans
    whistles. If I am on Linux, I would use io_uring for SURE!


    Well, when in Rome? IOCP on Windows is the way to write a server, or
    a client for that matter. On my free time I am slowly but surely
    recreating my old proxy server code from around 2002. So far mostly
    from memory. Some of the API's are messing me up a little. Hard to
    remember them.

    On Linux AIO or io_uring. The fun part is that they have very similar
    logic to IOCP.


    So you never measure if complicated code is faster than the simple one
    or not.
    Somehow, it's what I expected.



    Why do you assume that? IOCP is WAY more efficient than using say,
    select, or the event based thing using WaitForMultipleObjects. AIO or io_uring is way more efficient than using select, even epoll iirc.

    If you are building a robust server that is meant to scale up, we need
    these API's.

    Back in the day, 20+ years ago I experimented with all sort of
    completion techniques. Worst by far is the thread per connection crap.
    It does not scale at all. Actually, WaitForMultipleObjects worked kind
    of okay but we must remember to scramble or shift the objects in the
    array to avoid starvation. select did not scale, etc... IOCP on Windows
    is bar none, the way to go.

    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Chris M. Thomasson@3:633/10 to All on Sat Jul 18 17:37:41 2026
    On 7/18/2026 1:12 PM, Michael S wrote:
    On Fri, 17 Jul 2026 12:00:55 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> wrote:

    On 7/17/2026 3:32 AM, Michael S wrote:
    On Thu, 16 Jul 2026 12:37:20 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> wrote:

    If I am on Windows I use IOCP and use all of it, all the bells ans
    whistles. If I am on Linux, I would use io_uring for SURE!



    Well, when in Rome? IOCP on Windows is the way to write a server, or
    a client for that matter. On my free time I am slowly but surely
    recreating my old proxy server code from around 2002. So far mostly
    from memory. Some of the API's are messing me up a little. Hard to
    remember them.

    On Linux AIO or io_uring. The fun part is that they have very similar
    logic to IOCP.


    So you never measure if complicated code is faster than the simple one
    or not.
    Somehow, it's what I expected.



    Fwiw, https://www.devdigest.org/articles/epoll-vs-io-uring-why-linux-async-io-changed-forever

    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Michael S@3:633/10 to All on Sun Jul 19 04:56:39 2026
    On Sat, 18 Jul 2026 17:18:48 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> wrote:

    On 7/18/2026 5:15 PM, Chris M. Thomasson wrote:
    On 7/18/2026 1:12 PM, Michael S wrote:
    On Fri, 17 Jul 2026 12:00:55 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> wrote:

    On 7/17/2026 3:32 AM, Michael S wrote:
    On Thu, 16 Jul 2026 12:37:20 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> wrote:

    If I am on Windows I use IOCP and use all of it, all the bells
    ans whistles. If I am on Linux, I would use io_uring for SURE!


    Well, when in Rome? IOCP on Windows is the way to write a server,
    or a client for that matter. On my free time I am slowly but
    surely recreating my old proxy server code from around 2002. So
    far mostly from memory. Some of the API's are messing me up a
    little. Hard to remember them.

    On Linux AIO or io_uring. The fun part is that they have very
    similar logic to IOCP.


    So you never measure if complicated code is faster than the simple
    one or not.
    Somehow, it's what I expected.



    Why do you assume that? IOCP is WAY more efficient than using say,
    select, or the event based thing using WaitForMultipleObjects. AIO
    or io_uring is way more efficient than using select, even epoll
    iirc.

    If you are building a robust server that is meant to scale up, we
    need these API's.

    Back in the day, 20+ years ago I experimented with all sort of
    completion techniques. Worst by far is the thread per connection
    crap. It does not scale at all. Actually, WaitForMultipleObjects
    worked kind of okay but we must remember to scramble or shift the
    objects in the array to avoid starvation. select did not scale,
    etc... IOCP on Windows is bar none, the way to go.



    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Michael S@3:633/10 to All on Sun Jul 19 05:00:30 2026
    On Sat, 18 Jul 2026 17:18:48 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> wrote:

    On 7/18/2026 5:15 PM, Chris M. Thomasson wrote:
    On 7/18/2026 1:12 PM, Michael S wrote:
    On Fri, 17 Jul 2026 12:00:55 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> wrote:

    On 7/17/2026 3:32 AM, Michael S wrote:
    On Thu, 16 Jul 2026 12:37:20 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> wrote:

    If I am on Windows I use IOCP and use all of it, all the bells
    ans whistles. If I am on Linux, I would use io_uring for SURE!


    Well, when in Rome? IOCP on Windows is the way to write a server,
    or a client for that matter. On my free time I am slowly but
    surely recreating my old proxy server code from around 2002. So
    far mostly from memory. Some of the API's are messing me up a
    little. Hard to remember them.

    On Linux AIO or io_uring. The fun part is that they have very
    similar logic to IOCP.


    So you never measure if complicated code is faster than the simple
    one or not.
    Somehow, it's what I expected.



    Why do you assume that? IOCP is WAY more efficient than using say,
    select, or the event based thing using WaitForMultipleObjects. AIO
    or io_uring is way more efficient than using select, even epoll
    iirc.

    If you are building a robust server that is meant to scale up, we
    need these API's.

    Back in the day, 20+ years ago I experimented with all sort of
    completion techniques. Worst by far is the thread per connection
    crap. It does not scale at all. Actually, WaitForMultipleObjects
    worked kind of okay but we must remember to scramble or shift the
    objects in the array to avoid starvation. select did not scale,
    etc... IOCP on Windows is bar none, the way to go.

    What was correct 20+ years ago (would not surprise me if in fact
    your measurements were done 25+ years ago) is VERY likely to be wrong
    today.
    Esp. so for servers that never see a lot of load. Definition of "a
    lot" also changed.








    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From boltar@3:633/10 to All on Sun Jul 19 07:57:23 2026
    On Sat, 18 Jul 2026 17:15:28 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/18/2026 1:12 PM, Michael S wrote:
    On Fri, 17 Jul 2026 12:00:55 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> wrote:
    So you never measure if complicated code is faster than the simple one
    or not.
    Somehow, it's what I expected.



    Why do you assume that? IOCP is WAY more efficient than using say,
    select, or the event based thing using WaitForMultipleObjects. AIO or >io_uring is way more efficient than using select, even epoll iirc.

    If you are building a robust server that is meant to scale up, we need
    these API's.

    I've never used io_uring on linux but just looking at the man page makes
    me want to run for the hills. Setup and retrieval looks highly complicated with C pointers all over the place. Frankly the io_uring_sqe structure is a horror story. There are probably easier ways to get high server throughput
    than dicking about with this awful API.


    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Chris M. Thomasson@3:633/10 to All on Sun Jul 19 13:54:06 2026
    On 7/18/2026 7:00 PM, Michael S wrote:
    On Sat, 18 Jul 2026 17:18:48 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> wrote:

    On 7/18/2026 5:15 PM, Chris M. Thomasson wrote:
    On 7/18/2026 1:12 PM, Michael S wrote:
    On Fri, 17 Jul 2026 12:00:55 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> wrote:

    On 7/17/2026 3:32 AM, Michael S wrote:
    On Thu, 16 Jul 2026 12:37:20 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> wrote:

    If I am on Windows I use IOCP and use all of it, all the bells
    ans whistles. If I am on Linux, I would use io_uring for SURE!


    Well, when in Rome? IOCP on Windows is the way to write a server,
    or a client for that matter. On my free time I am slowly but
    surely recreating my old proxy server code from around 2002. So
    far mostly from memory. Some of the API's are messing me up a
    little. Hard to remember them.

    On Linux AIO or io_uring. The fun part is that they have very
    similar logic to IOCP.


    So you never measure if complicated code is faster than the simple
    one or not.
    Somehow, it's what I expected.



    Why do you assume that? IOCP is WAY more efficient than using say,
    select, or the event based thing using WaitForMultipleObjects. AIO
    or io_uring is way more efficient than using select, even epoll
    iirc.

    If you are building a robust server that is meant to scale up, we
    need these API's.

    Back in the day, 20+ years ago I experimented with all sort of
    completion techniques. Worst by far is the thread per connection
    crap. It does not scale at all. Actually, WaitForMultipleObjects
    worked kind of okay but we must remember to scramble or shift the
    objects in the array to avoid starvation. select did not scale,
    etc... IOCP on Windows is bar none, the way to go.

    What was correct 20+ years ago (would not surprise me if in fact
    your measurements were done 25+ years ago) is VERY likely to be wrong
    today.
    Esp. so for servers that never see a lot of load. Definition of "a
    lot" also changed.

    A lot of load back then was around 50 to 60 thousand concurrent
    connections all loaded with activity, some random disconnects, graceful shutdowns, connect then artificially wait trying to blow the server up,
    need timeout detection here, anyway... Thread per connections were crap
    wrt scalability! BIG TIME! IOCP on Windows, the only way.


    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Chris M. Thomasson@3:633/10 to All on Sun Jul 19 13:54:51 2026
    On 7/19/2026 12:57 AM, boltar@caprica.universe wrote:
    On Sat, 18 Jul 2026 17:15:28 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/18/2026 1:12 PM, Michael S wrote:
    On Fri, 17 Jul 2026 12:00:55 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> wrote:
    So you never measure if complicated code is faster than the simple one
    or not.
    Somehow, it's what I expected.



    Why do you assume that? IOCP is WAY more efficient than using say,
    select, or the event based thing using WaitForMultipleObjects. AIO or
    io_uring is way more efficient than using select, even epoll iirc.

    If you are building a robust server that is meant to scale up, we need
    these API's.

    I've never used io_uring on linux but just looking at the man page makes
    me want to run for the hills. Setup and retrieval looks highly
    complicated with C pointers all over the place. Frankly the io_uring_sqe structure is a horror story. There are probably easier ways to get high server throughput
    than dicking about with this awful API.


    Make your own. Heck... io_uring is more low level than IOCP!

    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Chris M. Thomasson@3:633/10 to All on Sun Jul 19 13:55:37 2026
    On 7/17/2026 2:27 AM, boltar@caprica.universe wrote:
    On Thu, 16 Jul 2026 12:40:42 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/16/2026 3:44 AM, boltar@caprica.universe wrote:
    On Wed, 15 Jul 2026 15:51:10 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/15/2026 8:54 AM, boltar@caprica.universe wrote:
    On Wed, 15 Jul 2026 14:07:58 GMT
    scott@slp53.sl.home (Scott Lurndal) gabbled:
    boltar@caprica.universe writes:
    On Tue, 14 Jul 2026 13:45:36 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:

    Huh? It saves a lot of work wrt closesocket, and calling WSASocket >>>>>>>
    I have no idea what "work" windows does with sockets but as I've >>>>>>> said more
    than once, on unix a socket is just an id number used to link
    userspace to

    Specifically, the socket(2) system call returns a standard file
    descriptor
    that can be used with the other file-related system calls such as >>>>>> read,
    write, poll/select, ioctl, etc.

    Indeed. Windows OTOH appears to have a specific C struct for
    sockets which
    seems
    unnecessarily complicated.


    Avoiding another call to WSASocket is beneficial.

    If windows didn't have a userspace struct representing a socket it
    wouldn't
    be needed in the first place.


    Why would you closesocket, when we can issue a DisconnectEx and once
    that per_io get completed in the io_worker thread pool, we can add the
    socket back to the per_socket pool(s), or just issue a new AcceptEx
    right there! No need to call closesocket, and then WSASocket again,
    right?

    No idea, I'm not a win32 developer. Windows seems to make a complete meal
    out of what should be - in userspace - a simple process.


    Make your own OS and show them how its done. ;^)

    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Chris M. Thomasson@3:633/10 to All on Sun Jul 19 13:57:11 2026
    On 7/19/2026 12:57 AM, boltar@caprica.universe wrote:
    On Sat, 18 Jul 2026 17:15:28 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> gabbled:
    On 7/18/2026 1:12 PM, Michael S wrote:
    On Fri, 17 Jul 2026 12:00:55 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> wrote:
    So you never measure if complicated code is faster than the simple one
    or not.
    Somehow, it's what I expected.



    Why do you assume that? IOCP is WAY more efficient than using say,
    select, or the event based thing using WaitForMultipleObjects. AIO or
    io_uring is way more efficient than using select, even epoll iirc.

    If you are building a robust server that is meant to scale up, we need
    these API's.

    I've never used io_uring on linux but just looking at the man page makes
    me want to run for the hills. Setup and retrieval looks highly
    complicated with C pointers all over the place. Frankly the io_uring_sqe structure is a horror story. There are probably easier ways to get high server throughput
    than dicking about with this awful API.


    Btw, if you don't like C... Well, don't use POSIX at all. Stay away from
    any linux C API's, etc... ;^)

    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From boltar@3:633/10 to All on Mon Jul 20 07:49:28 2026
    On Sun, 19 Jul 2026 13:55:37 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> wrote:
    On 7/17/2026 2:27 AM, boltar@caprica.universe wrote:
    No idea, I'm not a win32 developer. Windows seems to make a complete meal
    out of what should be - in userspace - a simple process.


    Make your own OS and show them how its done. ;^)

    I dont need to - thomson and Richie did it in 1969.


    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From boltar@3:633/10 to All on Mon Jul 20 07:51:40 2026
    On Sun, 19 Jul 2026 13:57:11 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> wrote:
    On 7/19/2026 12:57 AM, boltar@caprica.universe wrote:
    I've never used io_uring on linux but just looking at the man page makes
    me want to run for the hills. Setup and retrieval looks highly
    complicated with C pointers all over the place. Frankly the io_uring_sqe
    structure is a horror story. There are probably easier ways to get high
    server throughput
    than dicking about with this awful API.


    Btw, if you don't like C... Well, don't use POSIX at all. Stay away from
    any linux C API's, etc... ;^)

    I don't have a problem with C but I understand that it gets to a point
    where the complexity of something can overwhelm even the best developer
    and IMO io_uring has reached that point.

    Also its why I use C++ and so don't have to re-write my own hash function
    or red black tree container every time I write some code.



    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Chris M. Thomasson@3:633/10 to All on Mon Jul 20 13:15:51 2026
    On 7/20/2026 12:51 AM, boltar@battlestar-galactica.com wrote:
    On Sun, 19 Jul 2026 13:57:11 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> wrote:
    On 7/19/2026 12:57 AM, boltar@caprica.universe wrote:
    I've never used io_uring on linux but just looking at the man page makes >>> me want to run for the hills. Setup and retrieval looks highly
    complicated with C pointers all over the place. Frankly the
    io_uring_sqe structure is a horror story. There are probably easier
    ways to get high server throughput
    than dicking about with this awful API.


    Btw, if you don't like C... Well, don't use POSIX at all. Stay away
    from any linux C API's, etc... ;^)

    I don't have a problem with C but I understand that it gets to a point
    where the complexity of something can overwhelm even the best developer
    and IMO io_uring has reached that point.

    io_uring vs aio is way different at hyper low level. Almost akin to the difference between dx11 vs dx12, or Vulkan.

    Use it when you want to get scalable servers.

    Afaict, IOCP is the best windows has at the moment...


    Also its why I use C++ and so don't have to re-write my own hash function
    or red black tree container every time I write some code.

    Fair enough. C++ can handle low level as good as C can. Notice my atomic_region and my ralloc region allocator I posted in this thread?
    They can be used with io_uring. mmap, does not matter.

    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Chris M. Thomasson@3:633/10 to All on Mon Jul 20 13:16:54 2026
    On 7/20/2026 12:49 AM, boltar@battlestar-galactica.com wrote:
    On Sun, 19 Jul 2026 13:55:37 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> wrote:
    On 7/17/2026 2:27 AM, boltar@caprica.universe wrote:
    No idea, I'm not a win32 developer. Windows seems to make a complete
    meal
    out of what should be - in userspace - a simple process.


    Make your own OS and show them how its done. ;^)

    I dont need to - thomson and Richie did it in 1969.


    Well, patch the linux kernel, or the winnt kernel, and show them how you
    make use of your new socket infrastructure?

    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From boltar@3:633/10 to All on Tue Jul 21 15:55:37 2026
    On Mon, 20 Jul 2026 13:16:54 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> wrote:
    On 7/20/2026 12:49 AM, boltar@battlestar-galactica.com wrote:
    On Sun, 19 Jul 2026 13:55:37 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> wrote:
    On 7/17/2026 2:27 AM, boltar@caprica.universe wrote:
    No idea, I'm not a win32 developer. Windows seems to make a complete
    meal
    out of what should be - in userspace - a simple process.


    Make your own OS and show them how its done. ;^)

    I dont need to - thomson and Richie did it in 1969.


    Well, patch the linux kernel, or the winnt kernel, and show them how you >make use of your new socket infrastructure?

    I don't follow. All I'm saying is while its not perfect, the unix - and later posix - socket model is reasonably simple and dovetails nicely with other
    file descriptor based user subsystems. The only addition I would make is to make AF_INET sockets visible in the filesystem just like AF_UNIX ones.


    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Chris M. Thomasson@3:633/10 to All on Tue Jul 21 13:47:34 2026
    On 7/21/2026 8:55 AM, boltar@battlestar-galactica.com wrote:
    On Mon, 20 Jul 2026 13:16:54 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> wrote:
    On 7/20/2026 12:49 AM, boltar@battlestar-galactica.com wrote:
    On Sun, 19 Jul 2026 13:55:37 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> wrote:
    On 7/17/2026 2:27 AM, boltar@caprica.universe wrote:
    No idea, I'm not a win32 developer. Windows seems to make a
    complete meal
    out of what should be - in userspace - a simple process.


    Make your own OS and show them how its done. ;^)

    I dont need to - thomson and Richie did it in 1969.


    Well, patch the linux kernel, or the winnt kernel, and show them how
    you make use of your new socket infrastructure?

    I don't follow. All I'm saying is while its not perfect, the unix - and later
    posix - socket model is reasonably simple and dovetails nicely with other file descriptor based user subsystems. The only addition I would make is to make AF_INET sockets visible in the filesystem just like AF_UNIX ones.


    But, you are telling us how it should work, when you don't know how it
    does work?

    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From boltar@3:633/10 to All on Tue Jul 21 21:13:07 2026
    On Tue, 21 Jul 2026 13:47:34 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> wrote:
    On 7/21/2026 8:55 AM, boltar@battlestar-galactica.com wrote:
    On Mon, 20 Jul 2026 13:16:54 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> wrote:
    On 7/20/2026 12:49 AM, boltar@battlestar-galactica.com wrote:
    On Sun, 19 Jul 2026 13:55:37 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> wrote:
    On 7/17/2026 2:27 AM, boltar@caprica.universe wrote:
    No idea, I'm not a win32 developer. Windows seems to make a
    complete meal
    out of what should be - in userspace - a simple process.


    Make your own OS and show them how its done. ;^)

    I dont need to - thomson and Richie did it in 1969.


    Well, patch the linux kernel, or the winnt kernel, and show them how
    you make use of your new socket infrastructure?

    I don't follow. All I'm saying is while its not perfect, the unix - and
    later
    posix - socket model is reasonably simple and dovetails nicely with other
    file descriptor based user subsystems. The only addition I would make is to >> make AF_INET sockets visible in the filesystem just like AF_UNIX ones.


    But, you are telling us how it should work, when you don't know how it
    does work?

    I don't care about the kernel implementation, I'm talking about the userspace side. I'd have thought that was obvious.


    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Chris M. Thomasson@3:633/10 to All on Tue Jul 21 14:28:43 2026
    On 7/21/2026 2:13 PM, boltar@battlestar-galactica.com wrote:
    On Tue, 21 Jul 2026 13:47:34 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> wrote:
    On 7/21/2026 8:55 AM, boltar@battlestar-galactica.com wrote:
    On Mon, 20 Jul 2026 13:16:54 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> wrote:
    On 7/20/2026 12:49 AM, boltar@battlestar-galactica.com wrote:
    On Sun, 19 Jul 2026 13:55:37 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> wrote:
    On 7/17/2026 2:27 AM, boltar@caprica.universe wrote:
    No idea, I'm not a win32 developer. Windows seems to make a
    complete meal
    out of what should be - in userspace - a simple process.


    Make your own OS and show them how its done. ;^)

    I dont need to - thomson and Richie did it in 1969.


    Well, patch the linux kernel, or the winnt kernel, and show them how
    you make use of your new socket infrastructure?

    I don't follow. All I'm saying is while its not perfect, the unix -
    and later
    posix - socket model is reasonably simple and dovetails nicely with
    other
    file descriptor based user subsystems. The only addition I would make
    is to
    make AF_INET sockets visible in the filesystem just like AF_UNIX ones.


    But, you are telling us how it should work, when you don't know how it
    does work?

    I don't care about the kernel implementation, I'm talking about the userspace
    side. I'd have thought that was obvious.


    But the userspace side wrt sockets needs to work with the kernel side.

    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Dan Cross@3:633/10 to All on Wed Jul 22 01:53:29 2026
    In article <113ond3$2ncgf$1@dont-email.me>,
    <boltar@battlestar-galactica.com> wrote:
    On Tue, 21 Jul 2026 13:47:34 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> wrote:
    On 7/21/2026 8:55 AM, boltar@battlestar-galactica.com wrote:
    On Mon, 20 Jul 2026 13:16:54 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> wrote:
    On 7/20/2026 12:49 AM, boltar@battlestar-galactica.com wrote:
    On Sun, 19 Jul 2026 13:55:37 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> wrote:
    On 7/17/2026 2:27 AM, boltar@caprica.universe wrote:
    No idea, I'm not a win32 developer. Windows seems to make a
    complete meal
    out of what should be - in userspace - a simple process.


    Make your own OS and show them how its done. ;^)

    I dont need to - thomson and Richie did it in 1969.


    Well, patch the linux kernel, or the winnt kernel, and show them how
    you make use of your new socket infrastructure?

    I don't follow. All I'm saying is while its not perfect, the unix - and >>> later
    posix - socket model is reasonably simple and dovetails nicely with other >>> file descriptor based user subsystems. The only addition I would make is to >>> make AF_INET sockets visible in the filesystem just like AF_UNIX ones.


    But, you are telling us how it should work, when you don't know how it >>does work?

    I don't care about the kernel implementation, I'm talking about the userspace >side. I'd have thought that was obvious.

    Would you mind not changing your `From:` header, so that those
    of us who have plonked you don't have to keep updating our
    configurations? Thanks.

    - Dan C.


    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From boltar@3:633/10 to All on Wed Jul 22 08:01:52 2026
    On Tue, 21 Jul 2026 14:28:43 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> wrote:
    On 7/21/2026 2:13 PM, boltar@battlestar-galactica.com wrote:
    I don't care about the kernel implementation, I'm talking about the
    userspace
    side. I'd have thought that was obvious.


    But the userspace side wrt sockets needs to work with the kernel side.

    Are you an LLM? You seem to understand the meaning of words but get lost
    on the meaning of the whole post.


    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From boltar@3:633/10 to All on Wed Jul 22 08:02:38 2026
    On Wed, 22 Jul 2026 01:53:29 -0000 (UTC)
    cross@spitfire.i.gajendra.net (Dan Cross) wrote:
    In article <113ond3$2ncgf$1@dont-email.me>,
    I don't care about the kernel implementation, I'm talking about the userspace >>side. I'd have thought that was obvious.

    Would you mind not changing your `From:` header, so that those
    of us who have plonked you don't have to keep updating our
    configurations? Thanks.

    Why, are you afraid of learning something because it hurts?


    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Chris M. Thomasson@3:633/10 to All on Wed Jul 22 13:28:46 2026
    On 7/22/2026 1:01 AM, boltar@battlestar.co.uk wrote:
    On Tue, 21 Jul 2026 14:28:43 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> wrote:
    On 7/21/2026 2:13 PM, boltar@battlestar-galactica.com wrote:
    I don't care about the kernel implementation, I'm talking about the
    userspace
    side. I'd have thought that was obvious.


    But the userspace side wrt sockets needs to work with the kernel side.

    Are you an LLM? You seem to understand the meaning of words but get lost
    on the meaning of the whole post.


    No LLM, I have a long history on this group.

    You are the one that seems be be missing something... As if you no
    experience with using sockets?

    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Chris M. Thomasson@3:633/10 to All on Wed Jul 22 13:30:14 2026
    On 7/22/2026 1:02 AM, boltar@battlestar.co.uk wrote:
    On Wed, 22 Jul 2026 01:53:29 -0000 (UTC)
    cross@spitfire.i.gajendra.net (Dan Cross) wrote:
    In article <113ond3$2ncgf$1@dont-email.me>,
    I don't care about the kernel implementation, I'm talking about the userspace
    side. I'd have thought that was obvious.

    Would you mind not changing your `From:` header, so that those
    of us who have plonked you don't have to keep updating our
    configurations? Thanks.

    Why, are you afraid of learning something because it hurts?


    rofl. You are trolling! Never mind. Fell into your trap. Sorry.

    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Keith Thompson@3:633/10 to All on Wed Jul 22 16:02:13 2026
    boltar@battlestar.co.uk writes:
    On Wed, 22 Jul 2026 01:53:29 -0000 (UTC)
    cross@spitfire.i.gajendra.net (Dan Cross) wrote:
    In article <113ond3$2ncgf$1@dont-email.me>,
    I don't care about the kernel implementation, I'm talking about the userspace
    side. I'd have thought that was obvious.

    Would you mind not changing your `From:` header, so that those
    of us who have plonked you don't have to keep updating our
    configurations? Thanks.

    Why, are you afraid of learning something because it hurts?

    I won't speak for Dan, but since I've decided I don't want to read
    what you write (a decision I'm not required or inclined to explain), deliberately bypassing my filters is extremely rude.

    I currently have 4 variants of your posting address in my killfile,
    about to be 5. You appear to think that your judgement about whether
    I should read your posts is more important than mine. You're wrong.

    --
    Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
    void Void(void) { Void(); } /* The recursive call of the void */

    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Scott Lurndal@3:633/10 to All on Thu Jul 23 15:00:49 2026
    Keith Thompson <Keith.S.Thompson+u@gmail.com> writes:
    boltar@battlestar.co.uk writes:
    On Wed, 22 Jul 2026 01:53:29 -0000 (UTC)
    cross@spitfire.i.gajendra.net (Dan Cross) wrote:
    In article <113ond3$2ncgf$1@dont-email.me>,
    I don't care about the kernel implementation, I'm talking about the userspace
    side. I'd have thought that was obvious.

    Would you mind not changing your `From:` header, so that those
    of us who have plonked you don't have to keep updating our >>>configurations? Thanks.

    Why, are you afraid of learning something because it hurts?

    I won't speak for Dan, but since I've decided I don't want to read
    what you write (a decision I'm not required or inclined to explain), >deliberately bypassing my filters is extremely rude.

    I currently have 4 variants of your posting address in my killfile,
    about to be 5. You appear to think that your judgement about whether
    I should read your posts is more important than mine. You're wrong.

    Indeed, agreed.

    I'll note that "Gaius Baltar" in the Battlestar Galactica series
    was considered "weak", "arrogant" and "a coward"; narcissistic,
    self-centered, feckless and vain (https://en.wikipedia.org/wiki/Gaius_Baltar).

    The poster using that identity here seems to have embraced those characteristics, rather than the humble version that the
    fictional character later became.

    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From boltar@3:633/10 to All on Thu Jul 23 15:01:21 2026
    On Wed, 22 Jul 2026 13:28:46 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> wrote:
    On 7/22/2026 1:01 AM, boltar@battlestar.co.uk wrote:
    On Tue, 21 Jul 2026 14:28:43 -0700
    "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> wrote:
    On 7/21/2026 2:13 PM, boltar@battlestar-galactica.com wrote:
    I don't care about the kernel implementation, I'm talking about the
    userspace
    side. I'd have thought that was obvious.


    But the userspace side wrt sockets needs to work with the kernel side.

    Are you an LLM? You seem to understand the meaning of words but get lost
    on the meaning of the whole post.


    No LLM, I have a long history on this group.

    You are the one that seems be be missing something... As if you no >experience with using sockets?

    Oh you are funny :) FYI wrote my first program using sockets in 1992 and amongst other things I've written line handlers for a number of stock exchanges. Just because you know nothing about unix sockets API and are firmly stuck in win32 don't assume everyone else is an idiot.


    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From boltar@3:633/10 to All on Thu Jul 23 15:05:19 2026
    On Wed, 22 Jul 2026 16:02:13 -0700
    Keith Thompson <Keith.S.Thompson+u@gmail.com> wrote:
    boltar@battlestar.co.uk writes:
    Why, are you afraid of learning something because it hurts?

    I won't speak for Dan, but since I've decided I don't want to read
    what you write (a decision I'm not required or inclined to explain), >deliberately bypassing my filters is extremely rude.

    Oh please, this isn't 1985. I'll tell you what rude is - killfiling someone, hand waving away the reason then acting all hurt and wounded when you accidentaly read their post. Well diddums.

    I currently have 4 variants of your posting address in my killfile,
    about to be 5. You appear to think that your judgement about whether
    I should read your posts is more important than mine. You're wrong.

    I can make it 5000 if you like. The from address on this server is freeform and bears no relation to the account address.


    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)