added globalLock which protects against simultaneous access to the ring buffers....
[AROS.git] / arch / all-mingw32 / bsdsocket / bsdsocket_open.c
blobed782f0f717af9d180d061263b386a22f0c6d1d6
1 /*
2 Copyright © 1995-2014, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #include <aros/asmcall.h>
7 #include <aros/symbolsets.h>
8 #include <proto/exec.h>
10 #include "bsdsocket_intern.h"
11 #include "bsdsocket_util.h"
13 extern APTR BSDSocket_FuncTable[];
15 static AROS_UFH2(LONG, TaskKeyCompare,
16 AROS_UFHA(const struct AVLNode *, td, A0),
17 AROS_UFHA(AVLKey, key, A1))
19 AROS_USERFUNC_INIT
21 AVLKey id = ((struct TaskNode *)td)->task;
23 if (id == key)
24 return 0;
25 else if (id < key)
26 return -1;
27 else
28 return 1;
30 AROS_USERFUNC_EXIT
33 static AROS_UFH2(LONG, TaskNodeCompare,
34 AROS_UFHA(const struct AVLNode *, td1, A0),
35 AROS_UFHA(const struct AVLNode *, td2, A1))
37 AROS_USERFUNC_INIT
39 IPTR t1 = (IPTR)((struct TaskNode *)td1)->task;
40 IPTR t2 = (IPTR)((struct TaskNode *)td2)->task;
42 if (t1 == t2)
43 return 0;
44 else if (t1 < t2)
45 return -1;
46 else
47 return 1;
49 AROS_USERFUNC_EXIT
52 AROS_LH1(struct TaskBase *, BSDSocket_OpenLib,
53 AROS_LHA (ULONG, version, D0),
54 struct bsdsocketBase *, SocketBase, 1, BSDSocket)
56 AROS_LIBFUNC_INIT
58 struct TaskBase *tb;
59 struct Task *task = FindTask(NULL);
60 struct TaskNode *tn = (struct TaskNode *)AVL_FindNode(SocketBase->tasks, task, TaskKeyCompare);
62 D(bug("[OpenLib] Task 0x%p\n", task));
63 if (tn) {
64 tb = tn->self;
65 D(bug("[OpenLib] Found TaskBase 0x%p\n", tb));
66 } else {
67 APTR pool = CreatePool(MEMF_ANY, 2048, 1024);
69 D(bug("[OpenLib] Created pool 0x%p\n", pool));
70 if (!pool)
71 return NULL;
73 tb = (struct TaskBase *)MakeLibrary(BSDSocket_FuncTable, NULL, NULL, sizeof(struct TaskBase), NULL);
74 D(bug("[OpenLib] Created TaskBase 0x%p\n", tb));
75 if (!tb)
77 DeletePool(pool);
78 return NULL;
81 tb->lib.lib_Node.ln_Name = SocketBase->lib.lib_Node.ln_Name;
82 tb->lib.lib_Node.ln_Type = NT_LIBRARY;
83 tb->lib.lib_Node.ln_Pri = SocketBase->lib.lib_Node.ln_Pri;
84 tb->lib.lib_Flags = LIBF_CHANGED;
85 tb->lib.lib_Version = SocketBase->lib.lib_Version;
86 tb->lib.lib_Revision = SocketBase->lib.lib_Revision;
87 tb->lib.lib_IdString = SocketBase->lib.lib_IdString;
89 SumLibrary(&tb->lib);
91 tb->n.task = task;
92 tb->n.self = tb;
93 tb->glob = SocketBase;
94 tb->pool = pool;
95 tb->errnoPtr = &tb->errnoVal;
96 tb->errnoSize = sizeof(tb->errnoVal);
97 tb->sigintr = SIGBREAKF_CTRL_C;
99 SetDTableSize(FD_SETSIZE, tb);
101 AVL_AddNode(&SocketBase->tasks, &tb->n.node, TaskNodeCompare);
104 if (tb)
106 tb->lib.lib_OpenCnt++;
107 SocketBase->lib.lib_OpenCnt++;
108 D(bug("[socket] Task open count %u, global open count %u\n", tb->lib.lib_OpenCnt, SocketBase->lib.lib_OpenCnt));
111 return tb;
113 AROS_LIBFUNC_EXIT
116 AROS_LH0(BPTR, BSDSocket_CloseLib,
117 struct TaskBase *, tb, 2, BSDSocket)
119 AROS_LIBFUNC_INIT
121 struct bsdsocketBase *SocketBase = tb->glob;
123 D(bug("[CloseLib] TaskBase 0x%p\n", tb));
125 tb->lib.lib_OpenCnt--;
126 SocketBase->lib.lib_OpenCnt--;
127 D(bug("[CloseLib] Task open count %u, global open count %u\n", tb->lib.lib_OpenCnt, SocketBase->lib.lib_OpenCnt));
129 if (!tb->lib.lib_OpenCnt)
131 APTR addr;
132 int i;
134 D(bug("[CloseLib] dTableSize is %u\n", tb->dTableSize));
135 for (i = 0; i < tb->dTableSize; i++)
136 IntCloseSocket(i, tb);
138 AVL_RemNodeByAddress(&SocketBase->tasks, &tb->n.node);
140 DeletePool(tb->pool);
142 addr = (APTR)tb - tb->lib.lib_NegSize;
143 FreeMem(addr, tb->lib.lib_NegSize + tb->lib.lib_PosSize);
146 if (SocketBase->lib.lib_OpenCnt)
147 return NULL;
149 if (SocketBase->lib.lib_Flags & LIBF_DELEXP)
150 return AROS_LC1(BPTR, BSDSocket_ExpungeLib,
151 AROS_LCA(struct bsdsocketBase *, SocketBase, D0),
152 struct bsdsocketBase *, SocketBase, 3, BSDSocket);
153 else
154 return NULL;
156 AROS_LIBFUNC_EXIT