<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html><body><div id="mbx-wrapper">
<div id="mbx-content" class="content" onfocus="didBecomeFirstResponder()" contenteditable="true" onblur="didBlur()">Responses inline. </div>
<div id="mbx-old-email" contenteditable="true">
<div class="mailbox_signature" style="display: block;">
<br>Best,<div>-Matt</div>
</div>
<span id="orc-full-body-initial-text" style="display: inline;"><br>On Tuesday, Aug 25, 2015 at 12:46 AM, Ken Thomases <<a href="mailto:ken@codeweavers.com" target="_blank">ken@codeweavers.com</a>>, wrote:<br></span><blockquote class="gmail_quote">Thanks for continuing to work on this. By no means a thorough review:
<br><br>> On Aug 24, 2015, at 10:49 PM, Matt Durgavich <mattdurgavich@gmail.com> wrote:
<br><br>> +#define CACHE_SIZE 256
<br>> +#define CACHE_DEPTH 16
<br>> +static SOCKET socket_cache[CACHE_SIZE][CACHE_DEPTH];
<br>> +
<br>> +/* Cache support */
<br>> +static void add_to_cache(SOCKET s);
<br>> +static BOOL remove_from_cache(SOCKET s);
<br>> +static BOOL socket_in_cache(SOCKET s);
<br><br>I'm not sure this is a "cache", per se. It's a hash table, but naming issues are fairly minor.
<br><br>
</blockquote>
<span class="mailbox-inline-edit"></span><div></div>
<span class="mailbox-inline-edit">Let's go with socket_table</span><div>
<br><blockquote class="gmail_quote">
<br>> @@ -1470,8 +1479,24 @@ int WINAPI WSAStartup(WORD wVersionRequested, LPWSADATA lpWSAData)
<br>> INT WINAPI WSACleanup(void)
<br>> {
<br>> if (num_startup) {
<br>> - num_startup--;
<br>> - TRACE("pending cleanups: %d\n", num_startup);
<br>> + /* WS_closesocket needs num_startup to be non-zero, so decrement afterwards */
<br>> + if (num_startup - 1 == 0) {
<br><br>Why not "if (num_startup == 1)"?
<br><br>> +static void add_to_cache(SOCKET s)
<br>> +{
<br>> + int index, depth;
<br>> + SOCKET old;
<br>> + LONG *dest;
<br>> + index = socket_to_index(s) % CACHE_SIZE;
<br><br>If you always mod the result of socket_to_index() by CACHE_SIZE, why not do that in that function?
<br><br>
</blockquote>
</div>
<span class="mailbox-inline-edit"></span><div></div>
<span class="mailbox-inline-edit">Point taken. </span><div>
<br><div><blockquote class="gmail_quote">
<br>> + for (depth = 0; depth < CACHE_DEPTH; ++depth) {
<br>> + if (socket_cache[index][depth] == 0)
<br>> + break;
<br>> + }
<br>> +
<br>> + if (depth == CACHE_DEPTH) {
<br>> + ERR("Socket hash table collision\n");
<br><br>This should exit here or you access beyond the end of socket_cache[index] just below.
<br><br>
</blockquote></div>
</div>
<span class="mailbox-inline-edit"></span><div></div>
<span class="mailbox-inline-edit">Good catch. </span><div>
<br><div><div><blockquote class="gmail_quote">
<br>> + }
<br>> +
<br>> + dest = (PLONG)&socket_cache[index][depth];
<br><br>Don't use PLONG, just use LONG*.
<br><br>
</blockquote></div></div>
</div>
<span class="mailbox-inline-edit"></span><div></div>
<span class="mailbox-inline-edit">Ok</span><div>
<br><div><div><div><blockquote class="gmail_quote">
<br>> + old = InterlockedExchange(dest, s);
<br>> +
<br>> + if (old != 0) {
<br>> + ERR("Socket hash table internal corruption");
<br><br>Reporting corruption isn't right. You should use InterlockedCompareExchange() with 0 as the comparand to _avoid_ corruption. If it fails, loop back to the depth loop and try again. The only error possible should be filling the hash table bucket.
<br><br>
</blockquote></div></div></div>
</div>
<span class="mailbox-inline-edit"></span><div></div>
<span class="mailbox-inline-edit">Right. Makes sense. Will fix. </span><div>
<br><div><div><div><div><blockquote class="gmail_quote">
<br>> + }
<br>> +}
<br>> +
<br>> +static BOOL remove_from_cache(SOCKET s)
<br>> +{
<br>> + int index,depth;
<br>> + SOCKET old;
<br>> + LONG *dest;
<br>> + index = socket_to_index(s) % CACHE_SIZE;
<br>> + for (depth = 0; depth < CACHE_DEPTH; ++depth) {
<br>> + if (socket_cache[index][depth] == s)
<br>> + break;
<br>> + }
<br>> +
<br>> + if (depth == CACHE_DEPTH) {
<br>> + return FALSE;
<br>> + }
<br>> +
<br>> + dest = (PLONG)&socket_cache[index][depth];
<br>> + old = InterlockedExchange(dest, 0);
<br>> + return (old == s);
<br><br>Under what circumstances could old not equal s? If that can happen, then this should also use InterlockedCompareExchange(), otherwise you've removed some other socket.
<br><br>
</blockquote></div></div></div></div>
</div>
<span class="mailbox-inline-edit"></span><div></div>
<span class="mailbox-inline-edit">If I fork a child, I'll inherit their sockets right? So some paranoia in the remove is needed. Unless wine doesn't work that way. I'll write it as the analog to add. </span><div>
<br><div><div><div><div><div>
<blockquote class="gmail_quote">
<br>-Ken
<br><br>
</blockquote>
<blockquote class="gmail_quote"></blockquote>
</div></div></div></div></div>
</div>
<span class="mailbox-inline-edit"></span><div></div>
<span class="mailbox-inline-edit">Thanks! I appreciate the feedback. </span><div>
<br><div><div><div><div><div><div><blockquote class="gmail_quote"><br></blockquote></div></div></div></div></div></div>
</div>
</div>
</div></body></html>