This is the mail archive of the
newlib-cvs@sourceware.org
mailing list for the newlib project.
[newlib-cygwin] Revert "ctype: align size of category bit fields to small targets needs"
- From: Corinna Vinschen <corinna at sourceware dot org>
- To: cygwin-cvs at sourceware dot org, newlib-cvs at sourceware dot org
- Date: 14 Mar 2018 10:53:56 -0000
- Subject: [newlib-cygwin] Revert "ctype: align size of category bit fields to small targets needs"
https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=edcf783dc2fc89f32a29443ceb5a362d0ee6910c
commit edcf783dc2fc89f32a29443ceb5a362d0ee6910c
Author: Corinna Vinschen <corinna@vinschen.de>
Date: Wed Mar 14 11:36:06 2018 +0100
Revert "ctype: align size of category bit fields to small targets needs"
This reverts commit e98d3eb3eb9b6abd897e102031a14b7057641a65.
It has accidentally included some work in progress.
Diff:
---
newlib/libc/ctype/categories.c | 4 +-
winsup/cygwin/fhandler.h | 117 ++++++-----------
winsup/cygwin/fhandler_socket_unix.cc | 229 ++++++++++++++--------------------
3 files changed, 136 insertions(+), 214 deletions(-)
diff --git a/newlib/libc/ctype/categories.c b/newlib/libc/ctype/categories.c
index c237324..db285d7 100644
--- a/newlib/libc/ctype/categories.c
+++ b/newlib/libc/ctype/categories.c
@@ -2,8 +2,8 @@
#include "categories.h"
struct _category {
- enum category cat: 8;
- unsigned int first: 24;
+ enum category cat: 11;
+ unsigned int first: 21;
unsigned short delta;
} __attribute__((packed));
diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h
index 2d11030..2e50208 100644
--- a/winsup/cygwin/fhandler.h
+++ b/winsup/cygwin/fhandler.h
@@ -579,8 +579,8 @@ class fhandler_socket: public fhandler_base
void set_addr_family (int af) {addr_family = af;}
int get_addr_family () {return addr_family;}
- virtual void set_socket_type (int st) { type = st;}
- virtual int get_socket_type () {return type;}
+ void set_socket_type (int st) { type = st;}
+ int get_socket_type () {return type;}
/* select.cc */
virtual select_record *select_read (select_stuff *) = 0;
@@ -825,38 +825,6 @@ class fhandler_socket_local: public fhandler_socket_wsock
}
};
-/* Sharable spinlock with low CPU profile and massively better
- performance than OS mutex or event solutions. */
-class af_unix_spinlock_t
-{
- LONG locked; /* 0 oder 1 */
-
-public:
- void lock ()
- {
- LONG ret = InterlockedExchange (&locked, 1);
- if (ret)
- {
- for (DWORD i = 0; ret; ++i)
- {
- Sleep ((i % 1024) >> 8);
- ret = InterlockedExchange (&locked, 1);
- }
- }
- }
- void unlock ()
- {
- InterlockedExchange (&locked, 0);
- }
-};
-
-/* Internal representation of shutdown states */
-enum shut_state {
- _SHUT_RECV = 1,
- _SHUT_SEND = 2,
- _SHUT_MASK = 3
-};
-
class sun_name_t
{
public:
@@ -867,10 +835,19 @@ class sun_name_t
/* Allows 108 bytes sun_path plus trailing NUL */
char _nul[sizeof (struct sockaddr_un) + 1];
};
- sun_name_t () { set (NULL, 0); }
- sun_name_t (const struct sockaddr *name, __socklen_t namelen)
- { set ((const struct sockaddr_un *) name, namelen); }
- void set (const struct sockaddr_un *name, __socklen_t namelen);
+ sun_name_t ();
+ sun_name_t (const struct sockaddr *name, __socklen_t namelen);
+
+ void *operator new (size_t) __attribute__ ((nothrow))
+ { return cmalloc_abort (HEAP_FHANDLER, sizeof (sun_name_t)); }
+ void operator delete (void *p) {cfree (p);}
+};
+
+/* Internal representation of shutdown states */
+enum shut_state {
+ _SHUT_READ = 1,
+ _SHUT_WRITE = 2,
+ _SHUT_RW = 3
};
/* For each AF_UNIX socket, we need to maintain socket-wide data,
@@ -878,29 +855,30 @@ class sun_name_t
in socket, socketpair or accept4 and reopened by dup, fork or exec. */
class af_unix_shmem_t
{
- /* Don't use SRWLOCKs here. They are not sharable. */
- af_unix_spinlock_t _bind_lock;
- af_unix_spinlock_t _conn_lock;
- af_unix_spinlock_t _state_lock;
- af_unix_spinlock_t _io_lock;
+ SRWLOCK _bind_lock;
+ SRWLOCK _conn_lock;
+ SRWLOCK _io_lock;
LONG _connection_state; /* conn_state */
LONG _binding_state; /* bind_state */
LONG _shutdown; /* shut_state */
LONG _so_error; /* SO_ERROR */
LONG _reuseaddr; /* dummy */
- int _type; /* socket type */
- sun_name_t sun_path;
- sun_name_t peer_sun_path;
public:
- void bind_lock () { _bind_lock.lock (); }
- void bind_unlock () { _bind_lock.unlock (); }
- void conn_lock () { _conn_lock.lock (); }
- void conn_unlock () { _conn_lock.unlock (); }
- void state_lock () { _state_lock.lock (); }
- void state_unlock () { _state_lock.unlock (); }
- void io_lock () { _io_lock.lock (); }
- void io_unlock () { _io_lock.unlock (); }
+ af_unix_shmem_t ()
+ : _connection_state (unconnected), _binding_state (unbound),
+ _shutdown (0), _so_error (0)
+ {
+ InitializeSRWLock (&_bind_lock);
+ InitializeSRWLock (&_conn_lock);
+ InitializeSRWLock (&_io_lock);
+ }
+ void bind_lock () { AcquireSRWLockExclusive (&_bind_lock); }
+ void bind_unlock () { ReleaseSRWLockExclusive (&_bind_lock); }
+ void conn_lock () { AcquireSRWLockExclusive (&_conn_lock); }
+ void conn_unlock () { ReleaseSRWLockExclusive (&_conn_lock); }
+ void io_lock () { AcquireSRWLockExclusive (&_io_lock); }
+ void io_unlock () { ReleaseSRWLockExclusive (&_io_lock); }
conn_state connect_state (conn_state val)
{ return (conn_state) InterlockedExchange (&_connection_state, val); }
@@ -921,20 +899,8 @@ class af_unix_shmem_t
int reuseaddr (int val)
{ return (int) InterlockedExchange (&_reuseaddr, val); }
int reuseaddr () const { return _reuseaddr; }
-
- void set_socket_type (int val) { _type = val; }
- int get_socket_type () const { return _type; }
-
- sun_name_t *get_sun_path () {return &sun_path;}
- sun_name_t *get_peer_sun_path () {return &peer_sun_path;}
- void set_sun_path (struct sockaddr_un *un, __socklen_t unlen)
- { sun_path.set (un, unlen); }
- void set_peer_sun_path (struct sockaddr_un *un, __socklen_t unlen)
- { peer_sun_path.set (un, unlen); }
};
-class af_unix_pkt_hdr_t;
-
class fhandler_socket_unix : public fhandler_socket
{
protected:
@@ -947,14 +913,14 @@ class fhandler_socket_unix : public fhandler_socket
HANDLE connect_wait_thr;
HANDLE cwt_termination_evt;
PVOID cwt_param;
+ sun_name_t *sun_path;
+ sun_name_t *peer_sun_path;
struct ucred peer_cred;
void bind_lock () { shmem->bind_lock (); }
void bind_unlock () { shmem->bind_unlock (); }
void conn_lock () { shmem->conn_lock (); }
void conn_unlock () { shmem->conn_unlock (); }
- void state_lock () { shmem->state_lock (); }
- void state_unlock () { shmem->state_unlock (); }
void io_lock () { shmem->io_lock (); }
void io_unlock () { shmem->io_unlock (); }
conn_state connect_state (conn_state val)
@@ -969,8 +935,6 @@ class fhandler_socket_unix : public fhandler_socket
int so_error () const { return shmem->so_error (); }
int reuseaddr (int err) { return shmem->reuseaddr (err); }
int reuseaddr () const { return shmem->reuseaddr (); }
- void set_socket_type (int val) { shmem->set_socket_type (val); }
- int get_socket_type () const { return shmem->get_socket_type (); }
int create_shmem ();
int reopen_shmem ();
@@ -996,14 +960,12 @@ class fhandler_socket_unix : public fhandler_socket
int connect_pipe (PUNICODE_STRING pipe_name);
int listen_pipe ();
int disconnect_pipe (HANDLE ph);
- sun_name_t *get_sun_path () {return shmem->get_sun_path ();}
- sun_name_t *get_peer_sun_path () {return shmem->get_peer_sun_path ();}
- void set_sun_path (struct sockaddr_un *un, __socklen_t unlen)
- { shmem->set_sun_path (un, unlen); }
+ sun_name_t *get_sun_path () {return sun_path;}
+ sun_name_t *get_peer_sun_path () {return peer_sun_path;}
+ void set_sun_path (struct sockaddr_un *un, __socklen_t unlen);
void set_sun_path (sun_name_t *snt)
{ snt ? set_sun_path (&snt->un, snt->un_len) : set_sun_path (NULL, 0); }
- void set_peer_sun_path (struct sockaddr_un *un, __socklen_t unlen)
- { shmem->set_peer_sun_path (un, unlen); }
+ void set_peer_sun_path (struct sockaddr_un *un, __socklen_t unlen);
void set_peer_sun_path (sun_name_t *snt)
{ snt ? set_peer_sun_path (&snt->un, snt->un_len)
: set_peer_sun_path (NULL, 0); }
@@ -1011,9 +973,6 @@ class fhandler_socket_unix : public fhandler_socket
void fixup_after_fork (HANDLE parent);
void fixup_after_exec ();
void set_close_on_exec (bool val);
- ssize_t recv_dgram (af_unix_pkt_hdr_t *packet, int flags);
- ssize_t recv_stream (af_unix_pkt_hdr_t *packet, int flags);
- ssize_t recv_eval (af_unix_pkt_hdr_t *packet, struct msghdr *msg, int flags);
public:
fhandler_socket_unix ();
diff --git a/winsup/cygwin/fhandler_socket_unix.cc b/winsup/cygwin/fhandler_socket_unix.cc
index 1bceaaf..79fc4bc 100644
--- a/winsup/cygwin/fhandler_socket_unix.cc
+++ b/winsup/cygwin/fhandler_socket_unix.cc
@@ -88,8 +88,6 @@ class af_unix_pkt_hdr_t
uint16_t cmsg_len; /* size of ancillary data block */
uint16_t data_len; /* size of user data */
- af_unix_pkt_hdr_t (uint8_t s, uint8_t n, uint16_t c, uint16_t d)
- { init (s, n, c, d); }
void init (uint8_t s, uint8_t n, uint16_t c, uint16_t d)
{
shut_info = s;
@@ -159,14 +157,19 @@ GUID __cygwin_socket_guid = {
/* Default timeout value of connect: 20 secs, as on Linux. */
#define AF_UNIX_CONNECT_TIMEOUT (-20 * NS100PERSEC)
-void
-sun_name_t::set (const struct sockaddr_un *name, socklen_t namelen)
+sun_name_t::sun_name_t ()
+{
+ un_len = sizeof (sa_family_t);
+ un.sun_family = AF_UNIX;
+ _nul[sizeof (struct sockaddr_un)] = '\0';
+}
+
+sun_name_t::sun_name_t (const struct sockaddr *name, socklen_t namelen)
{
if (namelen < 0)
namelen = 0;
un_len = namelen < (__socklen_t) sizeof un ? namelen : sizeof un;
- un.sun_family = AF_UNIX;
- if (name && un_len)
+ if (name)
memcpy (&un, name, un_len);
_nul[sizeof (struct sockaddr_un)] = '\0';
}
@@ -619,19 +622,21 @@ int
fhandler_socket_unix::send_my_name ()
{
sun_name_t *sun;
+ size_t name_len = 0;
af_unix_pkt_hdr_t *packet;
NTSTATUS status;
IO_STATUS_BLOCK io;
bind_lock ();
sun = get_sun_path ();
- packet = (af_unix_pkt_hdr_t *) alloca (sizeof *packet + sun->un_len);
+ name_len = sun ? sun->un_len : 0;
+ packet = (af_unix_pkt_hdr_t *) alloca (sizeof *packet + name_len);
if (sun)
- memcpy (AF_UNIX_PKT_NAME (packet), &sun->un, sun->un_len);
-
- packet->init (0, sun->un_len, 0, 0);
+ memcpy (AF_UNIX_PKT_NAME (packet), &sun->un, name_len);
bind_unlock ();
+ packet->init (0, name_len, 0, 0);
+
/* The theory: Fire and forget. */
io_lock ();
set_pipe_non_blocking (true);
@@ -1004,6 +1009,27 @@ fhandler_socket_unix::disconnect_pipe (HANDLE ph)
}
void
+fhandler_socket_unix::set_sun_path (struct sockaddr_un *un, socklen_t unlen)
+{
+ if (peer_sun_path)
+ delete peer_sun_path;
+ if (!un)
+ sun_path = NULL;
+ sun_path = new sun_name_t ((const struct sockaddr *) un, unlen);
+}
+
+void
+fhandler_socket_unix::set_peer_sun_path (struct sockaddr_un *un,
+ socklen_t unlen)
+{
+ if (peer_sun_path)
+ delete peer_sun_path;
+ if (!un)
+ peer_sun_path = NULL;
+ peer_sun_path = new sun_name_t ((const struct sockaddr *) un, unlen);
+}
+
+void
fhandler_socket_unix::set_cred ()
{
peer_cred.pid = (pid_t) 0;
@@ -1053,6 +1079,10 @@ fhandler_socket_unix::fhandler_socket_unix ()
fhandler_socket_unix::~fhandler_socket_unix ()
{
+ if (sun_path)
+ delete sun_path;
+ if (peer_sun_path)
+ delete peer_sun_path;
}
int
@@ -1064,12 +1094,6 @@ fhandler_socket_unix::dup (fhandler_base *child, int flags)
return -1;
}
fhandler_socket_unix *fhs = (fhandler_socket_unix *) child;
- if (reopen_shmem () < 0)
- {
- __seterrno ();
- fhs->close ();
- return -1;
- }
if (backing_file_handle && backing_file_handle != INVALID_HANDLE_VALUE
&& !DuplicateHandle (GetCurrentProcess (), backing_file_handle,
GetCurrentProcess (), &fhs->backing_file_handle,
@@ -1087,6 +1111,12 @@ fhandler_socket_unix::dup (fhandler_base *child, int flags)
fhs->close ();
return -1;
}
+ if (reopen_shmem () < 0)
+ {
+ __seterrno ();
+ fhs->close ();
+ return -1;
+ }
fhs->set_sun_path (get_sun_path ());
fhs->set_peer_sun_path (get_peer_sun_path ());
fhs->connect_wait_thr = NULL;
@@ -1218,7 +1248,7 @@ fhandler_socket_unix::socket (int af, int type, int protocol, int flags)
return -1;
rmem (262144);
wmem (262144);
- set_addr_family (AF_UNIX);
+ set_addr_family (af);
set_socket_type (type);
if (flags & SOCK_NONBLOCK)
set_nonblocking (true);
@@ -1249,17 +1279,13 @@ fhandler_socket_unix::socketpair (int af, int type, int protocol, int flags,
return -1;
}
- if (create_shmem () < 0)
- return -1;
- if (fh->create_shmem () < 0)
- goto fh_shmem_failed;
/* socket() on both sockets */
rmem (262144);
fh->rmem (262144);
wmem (262144);
fh->wmem (262144);
- set_addr_family (AF_UNIX);
- fh->set_addr_family (AF_UNIX);
+ set_addr_family (af);
+ fh->set_addr_family (af);
set_socket_type (type);
fh->set_socket_type (type);
set_unique_id ();
@@ -1268,15 +1294,31 @@ fhandler_socket_unix::socketpair (int af, int type, int protocol, int flags,
gen_pipe_name ();
pipe = create_pipe (true);
if (!pipe)
- goto create_pipe_failed;
+ return -1;
set_io_handle (pipe);
set_sun_path (&sun);
fh->set_peer_sun_path (&sun);
+ if (create_shmem () < 0)
+ {
+ NtClose (pipe);
+ return -1;
+ }
+ binding_state (bound);
connect_state (listener);
- /* connect 2nd socket, even for DGRAM. There's no difference as far
- as socketpairs are concerned. */
- if (fh->open_pipe (pc.get_nt_native_path (), false) < 0)
- goto fh_open_pipe_failed;
+ /* connect 2nd socket */
+ if (type != SOCK_DGRAM
+ && fh->open_pipe (pc.get_nt_native_path (), false) < 0)
+ {
+ NtClose (shmem_handle);
+ NtClose (pipe);
+ return -1;
+ }
+ if (fh->create_shmem () < 0)
+ {
+ NtClose (fh->get_handle ());
+ NtClose (shmem_handle);
+ NtClose (pipe);
+ }
fh->connect_state (connected);
if (flags & SOCK_NONBLOCK)
{
@@ -1289,16 +1331,6 @@ fhandler_socket_unix::socketpair (int af, int type, int protocol, int flags,
fh->set_close_on_exec (true);
}
return 0;
-
-fh_open_pipe_failed:
- NtClose (pipe);
-create_pipe_failed:
- NtUnmapViewOfSection (GetCurrentProcess (), fh->shmem);
- NtClose (fh->shmem_handle);
-fh_shmem_failed:
- NtUnmapViewOfSection (GetCurrentProcess (), shmem);
- NtClose (shmem_handle);
- return -1;
}
/* Bind creates the backing file, generates the pipe name and sets
@@ -1439,7 +1471,7 @@ fhandler_socket_unix::accept4 (struct sockaddr *peer, int *len, int flags)
if (sock->create_shmem () < 0)
goto create_shmem_failed;
- sock->set_addr_family (AF_UNIX);
+ sock->set_addr_family (get_addr_family ());
sock->set_socket_type (get_socket_type ());
if (flags & SOCK_NONBLOCK)
sock->set_nonblocking (true);
@@ -1577,60 +1609,36 @@ fhandler_socket_unix::connect (const struct sockaddr *name, int namelen)
int
fhandler_socket_unix::getsockname (struct sockaddr *name, int *namelen)
{
- sun_name_t *sun = get_sun_path ();
+ sun_name_t sun;
- memcpy (name, sun, MIN (*namelen, sun->un_len));
- *namelen = sun->un_len;
+ if (get_sun_path ())
+ memcpy (&sun, &get_sun_path ()->un, get_sun_path ()->un_len);
+ else
+ sun.un_len = 0;
+ memcpy (name, &sun, MIN (*namelen, sun.un_len));
+ *namelen = sun.un_len;
return 0;
}
int
fhandler_socket_unix::getpeername (struct sockaddr *name, int *namelen)
{
- sun_name_t *sun = get_peer_sun_path ();
- memcpy (name, sun, MIN (*namelen, sun->un_len));
- *namelen = sun->un_len;
+ sun_name_t sun;
+
+ if (get_peer_sun_path ())
+ memcpy (&sun, &get_peer_sun_path ()->un, get_peer_sun_path ()->un_len);
+ else
+ sun.un_len = 0;
+ memcpy (name, &sun, MIN (*namelen, sun.un_len));
+ *namelen = sun.un_len;
return 0;
}
int
fhandler_socket_unix::shutdown (int how)
{
- NTSTATUS status = STATUS_SUCCESS;
- IO_STATUS_BLOCK io;
-
- if (how < SHUT_RD || how > SHUT_RDWR)
- {
- set_errno (EINVAL);
- return -1;
- }
- /* Convert SHUT_RD/SHUT_WR/SHUT_RDWR to _SHUT_RECV/_SHUT_SEND bits. */
- ++how;
- state_lock ();
- int old_shutdown_mask = saw_shutdown ();
- int new_shutdown_mask = old_shutdown_mask | how;
- if (new_shutdown_mask != old_shutdown_mask)
- saw_shutdown (new_shutdown_mask);
- state_unlock ();
- if (new_shutdown_mask != old_shutdown_mask)
- {
- /* Send shutdown info to peer. Note that it's not necessarily fatal
- if the info isn't sent here. The info will be reproduced by any
- followup package sent to the peer. */
- af_unix_pkt_hdr_t packet (new_shutdown_mask, 0, 0, 0);
- io_lock ();
- set_pipe_non_blocking (true);
- status = NtWriteFile (get_handle (), NULL, NULL, NULL, &io, &packet,
- packet.pckt_len, NULL, NULL);
- set_pipe_non_blocking (is_nonblocking ());
- io_unlock ();
- }
- if (!NT_SUCCESS (status))
- {
- debug_printf ("Couldn't send shutdown info: NtWriteFile: %y", status);
- return -1;
- }
- return 0;
+ set_errno (EAFNOSUPPORT);
+ return -1;
}
int
@@ -1650,17 +1658,16 @@ fhandler_socket_unix::close ()
PVOID param = InterlockedExchangePointer (&cwt_param, NULL);
if (param)
cfree (param);
- HANDLE hdl = InterlockedExchangePointer (&get_handle (), NULL);
- if (hdl)
- NtClose (hdl);
- if (backing_file_handle && backing_file_handle != INVALID_HANDLE_VALUE)
- NtClose (backing_file_handle);
HANDLE shm = InterlockedExchangePointer (&shmem_handle, NULL);
if (shm)
NtClose (shm);
param = InterlockedExchangePointer ((PVOID *) &shmem, NULL);
if (param)
NtUnmapViewOfSection (GetCurrentProcess (), param);
+ if (get_handle ())
+ NtClose (get_handle ());
+ if (backing_file_handle && backing_file_handle != INVALID_HANDLE_VALUE)
+ NtClose (backing_file_handle);
return 0;
}
@@ -1674,77 +1681,33 @@ fhandler_socket_unix::getpeereid (pid_t *pid, uid_t *euid, gid_t *egid)
set_errno (EINVAL);
return -1;
}
+ conn_lock ();
if (connect_state () != connected)
set_errno (ENOTCONN);
else
{
__try
{
- state_lock ();
if (pid)
*pid = peer_cred.pid;
if (euid)
*euid = peer_cred.uid;
if (egid)
*egid = peer_cred.gid;
- state_unlock ();
ret = 0;
}
__except (EFAULT) {}
__endtry
}
+ conn_unlock ();
return ret;
}
ssize_t
-fhandler_socket_unix::recv_dgram (af_unix_pkt_hdr_t *packet, int flags)
-{
- /* socketpair sockets already have a valid pipe handle! */
- return 0;
-}
-
-ssize_t
-fhandler_socket_unix::recv_stream (af_unix_pkt_hdr_t *packet, int flags)
-{
-
- io_lock ();
- io_unlock ();
- return 0;
-}
-
-ssize_t
-fhandler_socket_unix::recv_eval (af_unix_pkt_hdr_t *packet, struct msghdr *msg,
- int flags)
-{
- return 0;
-}
-
-ssize_t
fhandler_socket_unix::recvmsg (struct msghdr *msg, int flags)
{
- tmp_pathbuf tp;
- af_unix_pkt_hdr_t *packet;
- ssize_t ret;
-
- if ((flags & ~(MSG_CMSG_CLOEXEC | MSG_DONTWAIT | MSG_OOB | MSG_PEEK
- | MSG_TRUNC | MSG_WAITALL)) != 0)
- {
- set_errno (EINVAL);
- return -1;
- }
- if (flags & MSG_OOB)
- {
- set_errno (EOPNOTSUPP);
- return -1;
- }
- if (saw_shutdown () & _SHUT_RECV)
- return 0; /* EOF */
- packet = (af_unix_pkt_hdr_t *) tp.t_get ();
- ret = (get_socket_type () == SOCK_DGRAM) ? recv_dgram (packet, flags)
- : recv_stream (packet, flags);
- if (ret > 0)
- ret = recv_eval (packet, msg, flags);
- return ret;
+ set_errno (EAFNOSUPPORT);
+ return -1;
}
ssize_t