diff options
author | Gustavo Padovan | 2016-06-11 09:11:19 -0500 |
---|---|---|
committer | Dmitry Shmidt | 2017-01-17 16:29:01 -0600 |
commit | 61ab0d74d218d0be32d0cab1c7ee22c5e12216fe (patch) | |
tree | 6525b8365ea63de8459cef0727fe63757d492424 /libsync | |
parent | ffc687baad033ecc96f6c560b205fea61afe9e41 (diff) | |
download | platform-system-core-61ab0d74d218d0be32d0cab1c7ee22c5e12216fe.tar.gz platform-system-core-61ab0d74d218d0be32d0cab1c7ee22c5e12216fe.tar.xz platform-system-core-61ab0d74d218d0be32d0cab1c7ee22c5e12216fe.zip |
libsync: add support to new Sync API
Change libsync functions in a way that it can run dynamically on both
APIs.
v2: fix whitespace changes and poll return handling
v3: handle error cases on sync_wait()
Test: Sync unit tests still passes.
Change-Id: I743ab92ce39cbfa75dca41dd0a435efa9f2aab66
hange-Id: Ib56f2c6441b41028bc9f66998676790b7713988a
Diffstat (limited to 'libsync')
-rw-r--r-- | libsync/sync.c | 126 |
1 files changed, 109 insertions, 17 deletions
diff --git a/libsync/sync.c b/libsync/sync.c index 5946096b0..9ed03dba8 100644 --- a/libsync/sync.c +++ b/libsync/sync.c | |||
@@ -20,6 +20,8 @@ | |||
20 | #include <malloc.h> | 20 | #include <malloc.h> |
21 | #include <stdint.h> | 21 | #include <stdint.h> |
22 | #include <string.h> | 22 | #include <string.h> |
23 | #include <errno.h> | ||
24 | #include <poll.h> | ||
23 | 25 | ||
24 | #include <sys/ioctl.h> | 26 | #include <sys/ioctl.h> |
25 | #include <sys/stat.h> | 27 | #include <sys/stat.h> |
@@ -40,43 +42,133 @@ struct sw_sync_create_fence_data { | |||
40 | 42 | ||
41 | int sync_wait(int fd, int timeout) | 43 | int sync_wait(int fd, int timeout) |
42 | { | 44 | { |
43 | __s32 to = timeout; | 45 | struct pollfd fds; |
46 | int ret; | ||
47 | |||
48 | if (fd < 0) { | ||
49 | errno = EINVAL; | ||
50 | return -1; | ||
51 | } | ||
52 | |||
53 | fds.fd = fd; | ||
54 | fds.events = POLLIN; | ||
55 | |||
56 | do { | ||
57 | ret = poll(&fds, 1, timeout); | ||
58 | if (ret > 0) { | ||
59 | if (fds.revents & (POLLERR | POLLNVAL)) { | ||
60 | errno = EINVAL; | ||
61 | return -1; | ||
62 | } | ||
63 | return 0; | ||
64 | } else if (ret == 0) { | ||
65 | errno = ETIME; | ||
66 | return -1; | ||
67 | } | ||
68 | } while (ret == -1 && (errno == EINTR || errno == EAGAIN)); | ||
44 | 69 | ||
45 | return ioctl(fd, SYNC_IOC_LEGACY_WAIT, &to); | 70 | return ret; |
46 | } | 71 | } |
47 | 72 | ||
48 | int sync_merge(const char *name, int fd1, int fd2) | 73 | int sync_merge(const char *name, int fd1, int fd2) |
49 | { | 74 | { |
50 | struct sync_legacy_merge_data data; | 75 | struct sync_legacy_merge_data legacy_data; |
51 | int err; | 76 | struct sync_merge_data data; |
77 | int ret; | ||
52 | 78 | ||
53 | data.fd2 = fd2; | 79 | data.fd2 = fd2; |
54 | strlcpy(data.name, name, sizeof(data.name)); | 80 | strlcpy(data.name, name, sizeof(data.name)); |
81 | data.flags = 0; | ||
82 | data.pad = 0; | ||
55 | 83 | ||
56 | err = ioctl(fd1, SYNC_IOC_LEGACY_MERGE, &data); | 84 | ret = ioctl(fd1, SYNC_IOC_MERGE, &data); |
57 | if (err < 0) | 85 | if (ret < 0 && errno == ENOTTY) { |
58 | return err; | 86 | legacy_data.fd2 = fd2; |
87 | strlcpy(legacy_data.name, name, sizeof(legacy_data.name)); | ||
88 | |||
89 | ret = ioctl(fd1, SYNC_IOC_LEGACY_MERGE, &legacy_data); | ||
90 | if (ret < 0) | ||
91 | return ret; | ||
92 | |||
93 | return legacy_data.fence; | ||
94 | } else if (ret < 0) { | ||
95 | return ret; | ||
96 | } | ||
59 | 97 | ||
60 | return data.fence; | 98 | return data.fence; |
61 | } | 99 | } |
62 | 100 | ||
63 | struct sync_fence_info_data *sync_fence_info(int fd) | 101 | struct sync_fence_info_data *sync_fence_info(int fd) |
64 | { | 102 | { |
65 | struct sync_fence_info_data *info; | 103 | struct sync_fence_info_data *legacy_info; |
66 | int err; | 104 | struct sync_pt_info *legacy_pt_info; |
67 | 105 | struct sync_file_info *info; | |
68 | info = malloc(4096); | 106 | struct sync_fence_info *fence_info; |
69 | if (info == NULL) | 107 | int err, num_fences, i; |
108 | |||
109 | legacy_info = malloc(4096); | ||
110 | if (legacy_info == NULL) | ||
70 | return NULL; | 111 | return NULL; |
71 | 112 | ||
72 | info->len = 4096; | 113 | legacy_info->len = 4096; |
73 | err = ioctl(fd, SYNC_IOC_LEGACY_FENCE_INFO, info); | 114 | err = ioctl(fd, SYNC_IOC_LEGACY_FENCE_INFO, legacy_info); |
74 | if (err < 0) { | 115 | if (err < 0 && errno != ENOTTY) { |
75 | free(info); | 116 | free(legacy_info); |
76 | return NULL; | 117 | return NULL; |
118 | } else if (err == 0) { | ||
119 | return legacy_info; | ||
120 | } | ||
121 | |||
122 | info = calloc(1, sizeof(*info)); | ||
123 | if (info == NULL) | ||
124 | goto free; | ||
125 | |||
126 | err = ioctl(fd, SYNC_IOC_FILE_INFO, info); | ||
127 | if (err < 0) | ||
128 | goto free; | ||
129 | |||
130 | num_fences = info->num_fences; | ||
131 | |||
132 | if (num_fences) { | ||
133 | info->flags = 0; | ||
134 | info->num_fences = num_fences; | ||
135 | info->sync_fence_info = (uint64_t) calloc(num_fences, | ||
136 | sizeof(struct sync_fence_info)); | ||
137 | if ((void *)info->sync_fence_info == NULL) | ||
138 | goto free; | ||
139 | |||
140 | err = ioctl(fd, SYNC_IOC_FILE_INFO, info); | ||
141 | if (err < 0) { | ||
142 | free((void *)info->sync_fence_info); | ||
143 | goto free; | ||
144 | } | ||
145 | } | ||
146 | |||
147 | legacy_info->len = sizeof(*legacy_info) + | ||
148 | num_fences * sizeof(struct sync_fence_info); | ||
149 | strlcpy(legacy_info->name, info->name, sizeof(legacy_info->name)); | ||
150 | legacy_info->status = info->status; | ||
151 | |||
152 | legacy_pt_info = (struct sync_pt_info *)legacy_info->pt_info; | ||
153 | fence_info = (struct sync_fence_info *)info->sync_fence_info; | ||
154 | for (i = 0 ; i < num_fences ; i++) { | ||
155 | legacy_pt_info[i].len = sizeof(*legacy_pt_info); | ||
156 | strlcpy(legacy_pt_info[i].obj_name, fence_info[i].obj_name, | ||
157 | sizeof(legacy_pt_info->obj_name)); | ||
158 | strlcpy(legacy_pt_info[i].driver_name, fence_info[i].driver_name, | ||
159 | sizeof(legacy_pt_info->driver_name)); | ||
160 | legacy_pt_info[i].status = fence_info[i].status; | ||
161 | legacy_pt_info[i].timestamp_ns = fence_info[i].timestamp_ns; | ||
77 | } | 162 | } |
78 | 163 | ||
79 | return info; | 164 | free((void *)info->sync_fence_info); |
165 | free(info); | ||
166 | return legacy_info; | ||
167 | |||
168 | free: | ||
169 | free(legacy_info); | ||
170 | free(info); | ||
171 | return NULL; | ||
80 | } | 172 | } |
81 | 173 | ||
82 | struct sync_pt_info *sync_pt_info(struct sync_fence_info_data *info, | 174 | struct sync_pt_info *sync_pt_info(struct sync_fence_info_data *info, |